MongoDB 查詢操作可實現大部分關係型數據庫的常用查詢操作,本文對 MongoDB 常用查詢進行講解。

在閱讀本文前,推薦先閱讀 《MongoDB 安裝及文檔的基本操作》

在進行操作講解前,先展示當前 MongoDB 中已存在的文檔,集合名稱 article

條件大小比較操作

查詢文檔時,對條件的大小、範圍進行過濾查詢,以下是常用比較操作符

操作符 說明
$eq 查詢與條件值相等的文檔,類似關係型數據庫的 =
$ne 查詢與條件值不相等或不存在的文檔,類似關係型數據庫的 !=
$gt 查詢大於條件值的文檔,類似關係型數據庫的 >
$gte 查詢大於或等於條件值的文檔,類似關係型數據庫的 >=
$lt 查詢小於條件值的文檔,類似關係型數據庫的 <
$lte 查詢小於或等於條件值的文檔,類似關係型數據庫的 <=
$in 查詢 $in 數據裏值的文檔,類似關係型數據庫的 in
$nin 與 $in 查詢相反,類似關係型數據庫的 not in

由於使用大於、小於、等於關係都差不多,比較好理解,這裏就舉一個例子說明,使用 $gte 來獲取大於或等於 150 的 visitor

db.article.find({"visitor": {$gte:150}})

執行結果:

使用 $in 時,必須用數組來設置條件值,比如獲取 visitor 爲 70150 的值

db.article.find({"visitor": {$in:[70, 150]}})

執行結果:

邏輯操作符

多條件查詢中,條件與條件連接符號叫做邏輯操作符。常用操作符:

操作符 說明
$and 表示所有條件同時滿足時成立
$nor $and 相反,所有條件都不滿足時成立
$or 只要有一個條件滿足則成立
$not 表示字段存在並且不符合條件

$and 查詢 author=ytaovisitor=150 的文檔

db.article.find(
    {$and:[
      {"author":{$eq:"ytao"}},
      {"visitor":{$eq:150}}
    ]}
)

$nor 查詢不是 author=ytao 和不是 visitor=170 的文檔

db.article.find(
    {$nor:[
      {"author":{$eq:"ytao"}},
      {"visitor":{$eq:170}}
    ]}
)

$or 查詢 author=ytaovisitor=170 的文檔

db.article.find(
    {$or:[
      {"author":{$eq:"ytao"}},
      {"visitor":{$eq:170}}
    ]}
)

$not 查詢不是 author=ytao 的文檔

db.article.find(
    {"author":{$not:{$eq:"ytao"}}}
)

元素操作符

對字段元素上的操作符叫做元素操作符

操作符 說明
$exists 判斷文檔中字段是否存在, true 爲存在, false 爲不存在
$type 篩選指定字段類型的文檔

$exists 查詢 author 字段存在的文檔

db.article.find(
    {"author":{$exists:true}}
)

$type 查詢 author 字段爲數組的文檔

db.article.find(
    {"author":{$type:"array"}}
)

正則表達式

MongoDB 支持正則表達式匹配文檔,通過正則表達我們可以實現關係型數據庫的模糊查詢,以及更加強大匹配規則,其使用語法有三種:

{ < field >: { $regex: /pattern/, $ options : '<options>' } }
{ < field >: { $regex: 'pattern', $ options : '<options>' } }
{ < field >: { $regex: /pattern/<options> } }

參數 /pattern/'pattern' 都是表示正則表達式,直接添加字符串可用來模糊查詢。

參數 $options 爲可選參數,有四個固定值選擇

options 選項 說明
i 匹配過程忽略大小寫
x 匹配過程忽略空格
m 匹配多行數據,但都是從每行的起點和結尾匹配
s 將多行轉換成一行後進行匹配,可匹配換行符 \n 字符串

模糊查詢 authorTao 的示例:

db.article.find(
    {"author":{$regex:/Tao/, $options:'i'}}
)

查詢結果

從上面查詢結果中可以看到,數據格式也可以進行匹配到。

聚合操作

聚合操作可以實現分組、排序、分頁、多集合關聯查詢等,使用語法格式:

db.collection.aggregate([
    {聚合操作一},
    {聚合操作二}
])

條件篩選

$match用來進行條件篩選,可以使用一些條件限制來進行查詢。

語法格式:

db.article.aggregate([
    { $match: <條件> }
])

查詢 author = ytaovisitor > 100 的文檔

db.article.aggregate([
    { $match: {
        $and: [
            {"author": {$eq: "ytao"}},
            {"visitor": {$gt: 100}}
        ]} 
    }
])

分組操作

$group是分組操作符,類似於關係型數據庫中的 group by 操作。其語法格式爲:

db.collection.aggregate([
    {
        $group:{
            "_id":"$<分組字段名>", 
            <顯示結果的字段名稱>:{<運算符>:"$<運算符計算的字段名>"}
        }
    }
])

其中運算符如下:

運算符 說明
$avg 當前組的平均數
$sum 當前組的總和
$min 當前組的最小值
$max 當前組的最大值
$first 當前組的第一個的值
$last 當前組的最後一個的值
$push 數組形式展示指定的當前組字段值
$addToSet 數組形式展示指定的當前組字段不重複值

分組求出每個 authorvisitor 平均數的例子

db.article.aggregate([
    {
        $group:{
            "_id":"$author", 
            "avg_visitor":{$sum:"$visitor"}
        }
    }
])

字段顯示

指定查詢後返回的字段使用 $project ,字段指定默認值爲 0 ,但是 _id 默認爲 1 ,顯示指定字段語法爲:

db.collection.aggregate([
    {
        $project:{
            "<字段名>": <0或1>, 
            "<字段名>":<0或1>
        }
    }
])

展示 titlevisitor 字段示例:

db.article.aggregate([
    {
        $project:{
            "_id": 0, 
            "title": 1,
            "visitor": 1
        }
    }
])

同時, $project 還以搭配 $split (字符串拆分)、 $substr (截取字符串)、 $concat (合併字符串)、 $switch (條件判斷)、 $toLower (轉換成小寫)、 $toUpper (轉換成大寫)、時間格式處理等等操作符進行操作,語法爲:

db.collection.aggregate([
    {
        $project:{
            "<字段名>": {<操作符>: <條件>}, 
            "<字段名>": {<操作符>: <條件>},
        }
    }
])

例如將 title 中的字母都轉換成大寫

db.article.aggregate([
    {
        $project:{
            "titleField":{ $toUpper:"$title" }
        }
    }
])

返回結果

排序操作

$sort是文檔排序操作符,類似關係型數據中的 order by 指令。 $sort 排序用 1-1 表示正序和倒序。

語法格式:

db.collection.aggregate([
    {
        $sort:{
            "<排序字段名>": <1 或 -1>
        }
    }
])

visitor 字段名進行倒序排序:

db.article.aggregate([
    {
        $sort:{
            "visitor": -1
        }
    }
])

排序結果

分頁操作

分頁使用 $skip$limit 進行分頁操作。 $skip 表示跳過文檔的數量, $limit 表示返回的文檔數量,這兩個指令使用,類似於關係型數據中的 limit <start>, <size> 分頁操作。

語法格式:

db.collection.aggregate([
    {$skip: <跳過的文檔數量>},
    {$limit: <返回的文檔數量>}
])

查詢第二頁的兩條數據示例:

db.article.aggregate([
    {$skip: 2},
    {$limit: 2}
])

返回結果

統計文檔數量

$count用來統計文檔數量,進行條件篩選時。

語法格式:

db.collection.aggregate([
    { $count: "<顯示數量的字段的名稱>" }
])

統計全部文檔數量:

db.article.aggregate([
    { $count: "數量" }
])

統計結果:

多集合關聯查詢

$lookup是用來多集合關聯查詢時使用的,類似於關係型數據庫中的聯表查詢。

使用語法:

db.collection.aggregate([
    { 
        $lookup: {
            from: <關聯的表名>,
            localField: <當前表的關聯字段>,
            foreignField: <關聯表的關聯字段>,
            as: <另一集合嵌入的字段名>
        }
    }
])

在進行多集合關聯查詢演示前,先添加一個集合 person ,裏面添加一條數據:

查詢 age = 18 的集合:

db.article.aggregate([
    { 
        $lookup: {
            from: "person",
            localField: "author",
            foreignField: "author",
            as: "person_info"
        }
    },
    {
       $match:{
           "person_info.age": {$eq: 18}
       }
    }
])

返回結果:

總結

對 MongoDB 的常用查詢操作進行了解後,可以發現它和關係型數據操作有很多類似的操作思想。對於這些操作的使用,相對也是較爲靈活,提供的 API 也是較爲強大,幾乎能滿足大部分使用場景的檢索要求。掌握這些查詢操作,可以更高效的獲取 MongoDB 中的文檔。

相關文章