动态

详情 返回 返回

MongoDB 的文檔查詢操作 - 动态 详情

前置知識

find 語法

格式:db.COLLECTION_NAME.find(query, projection)

參數説明:

  • query:可選,使用查詢操作符指定的查詢條件。
  • projection:可選,使用投影操作符指定返回的鍵。如果要在查詢時返回文檔中所有鍵值,只需省略該參數即可(默認為省略)。

文檔查詢條件的構造可以參考下表所示。

操作 格式 範例
等於 {<key>:<value>} db.col.find({"by":"x"})
小於 {<key>:{$lt:<value>}} db.col.find("likes":{$lt:50}})
小於等於 {<key>:{$lte:<value>}} db.col.find(("likes":{$lte:50}})
大於 {<key>:{$gt:<value>}} db.col.find("likes":{$gt:50}})
大於等於 {<key>:{$gte:<value>}} db.col.find("likes":{$gte:50}})
不等於 {<key>:{$ne:<value>}} db.col.find("likes":{$ne:50}})
包含 {<key>:{$in:[<value1>,...,<valueN>]}} db.col.find("likes":{$in:[2,3,4]}})
不包含 {<key>:{$nin:[<value1>,...,<valueN>]}} db.col.find("likes":{$nin:[2,3,4]}})
{<key>:{$not:query}} db.col.find("likes":{$not:{$lt:50}}})

解釋 非where not likes < 50

aggregate() 聚合

db.COLLECTION_NAME.aggregate()

  • $sum:
  • $avg
  • $min
  • $max
  • $first
  • $last:根據資源文檔的排序獲取最後一個文檔數據

    db.mycol.aggregate([{$group:{_id:"$by_user", last_url:{$last:"$url"}}}])

可以使用 limit、skip、sort 限制返回結果數量、忽略一定數量結果、執行排序處理。

數據準備

創建實驗數據集合

itmes 集合,保存訂單信息。

db
db.createCollection("items")

image.png

插入文檔數據

pnumber:商品編號
quantity:商品數量
price:商品價格

db.items.insertMany([
{"quantity":2,"price":5.0, "pnumber":"p003"},
{"quantity":2,"price":8.0, "pnumber":"p002"},
{"quantity":1,"price":4.0, "pnumber":"p002"},
{"quantity":2,"price":4.0, "pnumber":"p001"},
{"quantity":4,"price":10.0, "pnumber":"p003"},
{"quantity":10,"price":20.0, "pnumber":"p001"},
{"quantity":10,"price":20.0, "pnumber":"p003"},
{"quantity":5,"price":10.0, "pnumber":"p002"}
])

image.png

格式化顯示文檔

db.items.find().pretty()

image.png

文檔查詢操作

(1) countDocuments()

統計集合中總共多少文檔

db.items.countDocuments({})

image.png

(2) distinct()

使用 distinct 命令查詢指定鍵的所有不同值,使用時必須指定集合和鍵。

例如,對 price 鍵使用 distinct,會得到所有不同的價格。
db.runCommand({"distinct":"items","key":"price"})

image.png

(3) 單條件查詢

例如,查詢價格大於5的商品數據,大於使用 gt 操作符,操作符前面要帶上 $ 符號。
db.items.find({price:{$gt:5}})

image.png

(4) 多條件查詢

多條件組合查詢,各個條件之間默認是 AND 關係。

例如,查詢 quantity 為 10 且價格大於等於 5 的商品數據。
db.items.find({quantity:10,price:{$gte:5}})

image.png

也可以使用 $or 來進行多條件查詢,語法格式如下:

db.collectionName.find(
{
    $or:[
      {key:value},
      {key:value}
    ]
})
例如,查詢 quantity 為 10 或價格大於等於 5 的商品數據。
db.items.find({$or:[{quantity:10},{price:{$gte:5}}]})

image.png

還可以將 AND 和 OR 聯合使用。

例如,查詢 pnumber 為"p003"且 quantity 為 10 或價格大於等於 5 的商品數據
db.items.find({
    pnumber:"p003",
    $or:[
        {quantity:10},
        {price:{$gte:5}}
    ]
})

image.png

(5) $in 查詢

例如,要找出 quantity為2、4、5的文檔。
db.items.find({quantity:{$in:[2,4,5]}})

image.png
$nin 將返回與數組中所有條件都不匹配的文檔。

要是想返回所有 quantity 不是2、4、5 的文檔,就可以用:
db.items.find({quantity:{$nin:[2,4,5]}})

image.png

説明

值得注意的是,$in能對單個鍵做OR查詢,但是要對多個鍵做查詢就得使用$or。
使用普通的AND型查詢時,總是希望儘可能用最少的條件來限定結果的範圍。OR型查詢正好相反,第一個條件應該儘可能匹配更多的文檔,這樣才是最為高效的。
$or 操作符在任何情況下都會正常工作,而如果查詢優化器可以更高效地處理$in,則應該優先選擇使用$in操作符。

(6) $not 查詢

以取模運算符 $mod 為例,$mod 會將查詢的值除以第一個給定值,若餘數等於第二個給定值則匹配成功。

例如,要查詢 quantity 值為奇數的文檔。
db.items.find({quantity:{$mod:[2,1]}})

image.png

要查詢 quantity 值為偶數的文檔,添加 $not
db.items.find({quantity:{$not:{$mod:[2,1]}}})

image.png

(7) null 查詢

null 不僅會匹配值為 null 的文檔,還會匹配不包含這個鍵的文檔(即返回缺少這個鍵的所有文檔)。

如果僅想匹配鍵值為 null 的文檔,則既要檢查該鍵的值是否為null,還要通過 $exists 條件判定鍵值已存在。

db.item.find({price:{$in:[null],$exists:true}})

image.png
由於沒有$eq(等於)操作符,所以這條查詢語句看上去麻煩,但是與只有一個元素的$in效果一樣。

(8) aggregate 聚合查詢

使用group可以執行更復雜的聚合。先選定分組所依據的鍵,而後MongoDB就會將集合依據選定鍵的不同值分成若干組。然後可以對每一個分組內的文檔進行聚合,最後可以得到一個結果文檔。

例如,統計訂單中所有商品的數量,即統計quantity的總和。
db.items.aggregate([{
    $group:{_id:null,total:{$sum:"$quantity"}}
}])

image.png

例如,通過產品類型來進行分組,然後在統計賣出的數量。
db.items.aggregate([{
$group:{_id:"$pnumber",total:{$sum:"$quantity"}}
}])

image.png

例如,通過相同的產品類型來進行分組,然後查詢相同產品類型中賣出最多的訂單詳情。
db.items.aggregate([{
$group:{_id:"$pnumber",max:{$max:"$quantity"}}
}])

image.png

例如,通過相同的產品類型來進行分組,然後查詢每個訂單詳情相同產品類型賣出的平均價格。
db.items.aggregate([{
$group:{_id:"$pnumber",price:{$avg:"$price"}}
}])

image.png

(9) 管道的使用

例如,希望先通過相同的產品類型來進行分組,統計出各個產品的數量,然後再獲取最大的數量,可以使用下面的命令。
db.items.aggregate([
{
    $group:{_id:"$pnumber",total:{$sum:"$quantity"}}
},
{
    $group:{_id:null, max:{$max:"$total"}}
}
])

image.png

(10) 查詢選項

1. limit

限制返回結果

db.items.find().limit(3)

image.png

2. skip

丟棄結果集中的前n個文檔,將剩餘文檔作為結果返回。在“普通”查詢中,如果需要跳過大量的數據,那麼這個操作符的效率會很低,因為它必須要先匹配到所有需要跳過的文檔,然後再將這些文檔丟棄。

例如,跳過前3個結果文檔,可以使用如下命令。
db.items.find().skip(3)

image.png

3. sort

接受一個對象作為參數,該對象是一組鍵/值對。

  • 鍵對應文檔的鍵名
  • 值代表排序的方向,排序方向可以是1(升序)或者-1(降序)
  • 如果指定了多個鍵,則按照這些鍵被指定的順序逐個排序。
例如,要按照pnumber升序以及 price降序排序,可以使用下面的命令。
db.items.find().sort({pnumber:1, price:-1})

image.png

4. 分頁

當點擊“下一頁”希望看到更多的結果時,可以通過skip非常簡單地實現,只需要略過前3個結果即可(因為前3個已經在第一頁顯示了)

db.items.find().limit(3).skip(3).sort({price:-1})

image.png

user avatar starrocks 头像 infinilabs 头像 sysin 头像 jiaolvdekaixinguo 头像 keen_626105e1ef632 头像
点赞 5 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.