MongoDB查詢總結
MongoDB查詢總結
介紹
前面寫過一篇關於Mongo�db的例子——,當時使用的只是簡單的查詢,然後後面業務變的有點複雜,原先沒有仔細研究過Mongodb的查詢,以為就是簡單呼叫下find
就可以了,乃衣服。
所以今天特地舉例說明一下Mongo中查詢問題。
Mongo查詢可以�分為2種:
普通查詢,類似於Sql中的
select where
聚合查詢,類似於Sql中的
group by
普通查詢
首先放一下,普通查詢主要用到db.collection.find()
函式。
定義下示例資料庫,下面是是初始化資料,可以在Mongo中的控制檯�執行。
db.inventory.insertMany([ { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" }, { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" }, { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" }, { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" }, { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" } ]);
查詢所有
db.inventory.find( {} )
對映Sql語句
SELECT * FROM inventory
條件查詢
語法格式
{: , ... }
比如查詢status
為D
記錄。
db.inventory.find( { status: "D" } )
對映Sql語句
SELECT * FROM inventory WHERE status = "D"
使用運算子進行條件查詢
語法格式
{: { : }, ... }
比如查詢滿足status
是�陣列[A,D]
中的記錄
db.inventory.find( { status: { $in: [ "A", "D" ] } } )
對映Sql語句
SELECT * FROM inventory WHERE status in ("A", "D")
AND 條件查詢
直接在find函式指定多個欄位滿足即可,這樣就是 and 條件。
比如下面語句就是 status
為 A
,qty
小於 30
。
db.inventory.find( { status: "A", qty: { $lt: 30 } } )
對映Sql語句
SELECT * FROM inventory WHERE status = "A" AND qty
OR 條件查詢
�OR 和 AND 就不一樣了,需要用到運算子 $or
,如下所示。
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
類似於SQL中的
SELECT * FROM inventory WHERE status = "A" OR qty
OR 和 AND 集合一起
db.inventory.find( { status: "A", $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ] } )
表示這樣的意思。
SELECT * FROM inventory WHERE status = "A" AND ( qty查詢舉例
查詢全部
SELECT *FROM people
db.people.find()
指定欄位
SELECT id, user_id, statusFROM people
db.people.find( { }, { user_id: 1, status: 1 } )
SELECT user_id, statusFROM people
指定欄位,不顯示
_id
db.people.find( { }, { user_id: 1, status: 1, _id: 0 } )
條件查詢全部
SELECT *FROM peopleWHERE status = "A"
db.people.find( { status: "A" } )
條件查詢�指定欄位
SELECT user_id, statusFROM peopleWHERE status = "A"
db.people.find( { status: "A" }, { user_id: 1, status: 1, _id: 0 } )
條件查詢不等於
SELECT *FROM peopleWHERE status != "A"
db.people.find( { status: { $ne: "A" } } )
條件查詢 AND
SELECT *FROM peopleWHERE status = "A"AND age = 50
db.people.find( { status: "A", age: 50 } )
條件查詢 OR
SELECT *FROM peopleWHERE status = "A"OR age = 50
db.people.find( { $or: [ { status: "A" } , { age: 50 } ] } )
條件查詢 �>
SELECT *FROM peopleWHERE age > 25
db.people.find( { age: { $gt: 25 } } )
條件查詢 �
SELECT *FROM peopleWHERE agedb.people.find( { age: { $lt: 25 } } )
�複雜的條件查詢
SELECT *FROM peopleWHERE age > 25AND agedb.people.find( { age: { $gt: 25, $lte: 50 } } )
條件查詢 �LIKE
SELECT *FROM peopleWHERE user_id like "%bc%"
db.people.find( { user_id: /bc/ } )// ORdb.people.find( { user_id: { $regex: /bc/ } } )
SELECT *FROM peopleWHERE user_id like "bc%"
db.people.find( { user_id: /^bc/ } )// ORdb.people.find( { user_id: { $regex: /^bc/ } } )
排序
SELECT *FROM peopleWHERE status = "A"ORDER BY user_id ASC
db.people.find( { status: "A" } ).sort( { user_id: 1 } )
SELECT *FROM peopleWHERE status = "A"ORDER BY user_id DESC
db.people.find( { status: "A" } ).sort( { user_id: -1 } )
統計數量
SELECT COUNT(*)FROM people
db.people.count()// ordb.people.find().count()
SELECT COUNT(user_id)FROM people
db.people.count( { user_id: { $exists: true } } )or
db.people.find( { user_id: { $exists: true } } ).count()
SELECT COUNT(*)FROM peopleWHERE age > 30
db.people.count( { age: { $gt: 30 } } )// ordb.people.find( { age: { $gt: 30 } } ).count()
去除重複distinct
SELECT DISTINCT(status)FROM people
db.people.distinct( "status" )
SELECT *FROM peopleLIMIT 1
限制數量
db.people.findOne() // or db.people.find().limit(1)
SELECT *FROM peopleLIMIT 5SKIP 10
db.people.find().limit(5).skip(10)
EXPLAIN
EXPLAIN SELECT *FROM peopleWHERE status = "A"
db.people.find( { status: "A" } ).explain()
聚合查詢
上面�普通查詢使用find
函式即可,但是聚合查詢使用另外一個函式aggregate
,這裡是。
初始化資料如下,有2個表 orders
和 order_lineitem
�,外來鍵關聯order_lineitem.order_id and the orders.id
。
{ cust_id: "abc123", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: 'A', price: 50, items: [ { sku: "xxx", qty: 25, price: 1 }, { sku: "yyy", qty: 25, price: 1 } ] }
統計數量
db.orders.aggregate( [ { $group: { _id: null, count: { $sum: 1 } } } ] )
對映Sql語句
SELECT COUNT(*) AS countFROM orders
計算總和
db.orders.aggregate( [ { $group: { _id: null, total: { $sum: "$price" } } } ] )
對映Sql語句
SELECT SUM(price) AS totalFROM orders
分組計算總和
db.orders.aggregate( [ { $group: { _id: "$cust_id", total: { $sum: "$price" } } } ] )
對映Sql語句
SELECT cust_id, SUM(price) AS totalFROM ordersGROUP BY cust_id
分組計算總和並排序
db.orders.aggregate( [ { $group: { _id: "$cust_id", total: { $sum: "$price" } } }, { $sort: { total: 1 } } ] )
對映Sql語句
SELECT cust_id, SUM(price) AS totalFROM ordersGROUP BY cust_idORDER BY tota
多個欄位分組
db.orders.aggregate( [ { $group: { _id: { cust_id: "$cust_id", ord_date: { month: { $month: "$ord_date" }, day: { $dayOfMonth: "$ord_date" }, year: { $year: "$ord_date"} } }, total: { $sum: "$price" } } } ] )
對映Sql語句
SELECT cust_id, ord_date, SUM(price) AS totalFROM ordersGROUP BY cust_id, ord_date
條件分組——HAVING
db.orders.aggregate( [ { $group: { _id: "$cust_id", count: { $sum: 1 } } }, { $match: { count: { $gt: 1 } } } ] )
對映Sql語句
SELECT cust_id, count(*)FROM ordersGROUP BY cust_idHAVING count(*) > 1
複雜條件分組統計
db.orders.aggregate( [ { $group: { _id: { cust_id: "$cust_id", ord_date: { month: { $month: "$ord_date" }, day: { $dayOfMonth: "$ord_date" }, year: { $year: "$ord_date"} } }, total: { $sum: "$price" } } }, { $match: { total: { $gt: 250 } } } ] )
對映Sql語句
SELECT cust_id, ord_date, SUM(price) AS totalFROM ordersGROUP BY cust_id, ord_dateHAVING total > 250
複雜條件分組統計示例1
db.orders.aggregate( [ { $match: { status: 'A' } }, { $group: { _id: "$cust_id", total: { $sum: "$price" } } } ] )
對映Sql語句
SELECT cust_id, SUM(price) as totalFROM ordersWHERE status = 'A'GROUP BY cust_id
複雜條件分組統計示例2
db.orders.aggregate( [ { $match: { status: 'A' } }, { $group: { _id: "$cust_id", total: { $sum: "$price" } } }, { $match: { total: { $gt: 250 } } } ] )
對映Sql語句
SELECT cust_id, SUM(price) as totalFROM ordersWHERE status = 'A'GROUP BY cust_idHAVING total > 250
表關聯
db.orders.aggregate( [ { $unwind: "$items" }, { $group: { _id: "$cust_id", qty: { $sum: "$items.qty" } } } ] )
對映Sql語句
SELECT cust_id, SUM(li.qty) as qtyFROM orders o, order_lineitem liWHERE li.order_id = o.idGROUP BY cust_id
巢狀查詢
db.orders.aggregate( [ { $group: { _id: { cust_id: "$cust_id", ord_date: { month: { $month: "$ord_date" }, day: { $dayOfMonth: "$ord_date" }, year: { $year: "$ord_date"} } } } }, { $group: { _id: null, count: { $sum: 1 } } } ] )
對映Sql語句
SELECT COUNT(*)FROM (SELECT cust_id, ord_date FROM orders GROUP BY cust_id, ord_date) as DerivedTable
Map-Reduce
Mongo中聚合查詢還有一種叫Map-Reduce,官方文件在,在思想上它跟Hadoop一樣,從一個單一集合中輸入資料,然後將結果輸出到一個集合中。通常在使用類似SQL中Group By
操作時,Map/Reduce會是一個好的工具。
Map-Reduce
介面方法定義
db.collection.mapReduce(
引數說明
mapReduce: 要執行Map/Reduce集合的名字
map: map 函式 (下面會詳細介紹)
reduce: reduce函式(下面會詳細介紹)
out: 存放結果的集合 (下面會詳細介紹)
query: 設定查詢條件
sort: 按某個鍵來排序
limit: 指明從集合檢索文件個數的最大值
finalize: 對reduce結果做進一步處理
scope: 指明透過map/reduce/finalize可以訪問到的變數
jsMode: 指明Map/Reduce執行過程中文件保持JSON狀態
verbose: 提供關於任務執行的統計資料
示例說明
�舉例說明Map-Reduce的用途,�雖然程式碼比較多,也行用上面的聚合查詢,一下子就搞定了,但是這裡只是舉例。
比如有個訂單表,如下所示,我們需要計算每個人的訂單總價。
{ _id: ObjectId("50a8240b927d5d8b5891743c"), cust_id: "abc123", ord_date: new Date("Oct 04, 2012"), status: 'A', price: 25, items: [ { sku: "mmm", qty: 5, price: 2.5 }, { sku: "nnn", qty: 5, price: 2.5 } ] }
首先定義Map方法,就說我們後面的聚合計算需要哪些欄位,�由於需要計算每個人的訂單總結,那麼個人資訊和加個肯定是我們需要的。
var mapFunction1 = function() { emit(this.cust_id, this.price); };
然後定義reduce方法,計算每個人的訂單價格。
var reduceFunction1 = function(keyCustId, valuesPrices) { return Array.sum(valuesPrices); };
然後儲存最後的計算結果。
db.orders.mapReduce( mapFunction1, reduceFunction1, { out: "map_reduce_example" } )
這樣一個簡單的Map-Reduce例項就完成了,結果放在map_reduce_example
中。
上面示例比較簡單,那麼我們來一個複雜一點的例子。
一條訂單記錄中,有sdk的名稱、數量、價格,那麼要查詢出日期大於01/01/2012
,所有訂單的總數,以及�平均sdk價格。
首先還是定義個map函式。
var mapFunction2 = function() { for (var idx = 0; idx然後算出sku的數量,和總價格。
var reduceFunction2 = function(keySKU, countObjVals) { reducedVal = { count: 0, qty: 0 }; for (var idx = 0; idx總價格出來後,還要計算出平均價格。
var finalizeFunction2 = function (key, reducedVal) { reducedVal.avg = reducedVal.qty / reducedVal.count; return reducedVal; };還有日期的條件過濾,最後得出完整的map-reduce。
db.orders.mapReduce( mapFunction2, reduceFunction2, { out: { merge: "map_reduce_example" }, query: { ord_date:{ $gt: new Date('01/01/2012') } }, finalize: finalizeFunction2 } )總結
以上就是我對MongoDB的示例總結,本人是一個初學者,也有很多地方不懂,如果有錯誤的地方,歡迎指出。
作者:流水不腐小夏
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4662/viewspace-2810585/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL查詢總結SQL
- mongodb查詢MongoDB
- MongoDB - 聚合查詢MongoDB
- 提高查詢速度方法總結
- SQL總結(一)基本查詢SQL
- SQL總結(三)其他查詢SQL
- Mongodb高階查詢MongoDB
- mongodb慢查詢分析MongoDB
- ❖ MongoDB 高階查詢MongoDB
- MongoDB查詢條件MongoDB
- MongoDB條件查詢MongoDB
- mysql查詢效能優化總結MySql優化
- SQL總結(二)連表查詢SQL
- SQL總結(七)查詢實戰SQL
- MySQL查詢結果匯出方式總結MySql
- Mybatis 查詢語句結果集總結MyBatis
- MongoDB 常用查詢語法MongoDB
- MongoDB查詢內嵌文件MongoDB
- MongoDB慢查詢與索引MongoDB索引
- Mongodb 關聯表查詢MongoDB
- MongoDB日期型別查詢MongoDB型別
- Mongodb 常用的查詢方法MongoDB
- Oracle總結【SQL細節、多表查詢、分組查詢、分頁】OracleSQL
- MySQL 索引及查詢優化總結MySql索引優化
- SQL單表查詢語句總結SQL
- 基礎二分查詢總結
- 關於字串匹配查詢的總結字串匹配
- MongoDB 如何支援類 SQL 查詢MongoDBSQL
- mongodb條件查詢不等於MongoDB
- MongoDB 操作文件 查詢文件MongoDB
- MongoDB的排除查詢$ne缺陷MongoDB
- MongoDB之資料查詢操作MongoDB
- MongoDB高階查詢詳細MongoDB
- 總結幾個查詢論文網址
- 【轉載】MySQL慢查詢日誌總結MySql
- 二分查詢實現----面試總結面試
- hibernate的hql查詢語句總結
- expdp/impdp的使用總結 (供查詢使用)