目錄:
- 聚合
- 更新
- 更新選擇器
- ObjectId
- 更新操作的原子性
聚合:
聚合語法:db.collectionName.aggregate(aggregate_operation)
聚合操作其實就是管道操作,上一次操作的結果集就是下一次管道的輸入數據。
1、$group:分組計算
- $sum、$avg、$min、$max:獲取分組集合中的總和、平均值、最大值、最小值
- $push:將指定表達式添加到一個數組中
- $addToSet:將指定表達式添加到集合中(無重復)
- $first:返回每組第一個文檔,如有排序按照排序返回,沒有則按照文檔的默認順序
- $last:同$first,但返回最后一個文檔
示例:
1、統計不同住址的用戶人數 db.users.aggregate({ '$group':{'_id':'$address', 'number':{'$sum':1}} }) 2、分別拿到每個住址區域中升高最高的 db.users.aggregate({ '$group':{'_id':'$address', 'number':{'$max':'$length'}} }) 3、分組用戶住址,並顯示此區域下所有的用戶姓名 db.users.aggregate({ '$group':{'_id':'$address', 'username':{'$push':'$username'}} }) 4、分組用戶住址,並顯示此區域下最后一名用戶的姓名 db.users.aggregate({ '$group':{'_id':'$address', 'lastUsername':{'$last':'$username'}} })
2、$project:輸出文檔中指定的字段。
示例:
1、獲取每個用戶的年齡及身高 db.users.aggregate({ '$project':{'age':1, 'length':1} })
3、$match:過濾數據,使用mongoDB標准的查詢操作($eq、$ne等等)。
示例:
1、獲取升高大於1.8的用戶姓名及身高
db.users.aggregate( {'$match':{'length':{'$gt':1.8}}}, {'$project':{'username':1, 'length':1}} )
4、$limit:限制文檔返回數量;$skip:跳過指定數量的文檔、$sort:排序(1=升序,-1=降序)。
示例:
1、獲取身高第二和第三高的用戶姓名 db.users.aggregate( {'$sort':{'length':-1}}, {'$skip':1}, {'$limit':2}, {'$project':{'username':1}} )
5、$unwind:將文檔中某一個數組拆分成多條。
示例:
1、獲取被評論次數最多的電影 db.users.aggregate( {'$unwind':'$comments'}, {'$group':{'_id':'$comments.movies', 'count':{'$sum':1}}}, {'$sort':{'count':-1}}, {'$limit':1}, {'$project':{'_id':1}} )
spring data mongoDB寫法見:https://github.com/mrjdrs/mongodb-demo/tree/master/mongo-selector
更新:
在mongo中更新分為兩種:
1、替換更新:使用新文檔替代舊文檔。
2、操作符更新:在一個或多個文檔上修改。
更新語法:
db.collectionName.update( <query>, <update>, {upsert:<boolean>, multi:<boolean>, wirteConcern:<document>} )
參數說明:
1、query:更新的查詢條件
2、update:更新操作符的選擇
3、upsert:若不存在更新的數據,是否插入一條新的數據;true=插入,false=不插入(默認)。
4、multi:是否更新多條,true=更新找到的多條數據,false=僅更新找到的第一條(默認)。
5、writeConcern:寫入數據的安全配置。
更新選擇器:
示例:
1、將java編程思想這本書籍價格加10 db.product.update( {'name':'java編程思想'}, {'$inc':{'price':10}} ) 2、更新java編程思想這本書名為java編程思想第四版 db.product.update( {'name':'java編程思想'}, {'$set':{'name':'java編程思想第四版'}} ) 3、將姓名為路飛,評論電影為戰狼的那條數據修改評論為戰狼電影的評論 // 注意$操作符一次只能修改一條數據 db.users.update( {'username':'路飛', 'comments.movies':'戰狼'}, {'$set':{'comments.$.content':'戰狼電影的評論'}} ) 4、為書籍java編程思想第四版添加兩個標簽值 db.product.update( {'name':'java編程思想第四版'}, {'$push':{'tags':{'$each':['標簽1', '標簽2']}}} )
spring data mongoDB寫法見:https://github.com/mrjdrs/mongodb-demo/tree/master/mongo-selector
ObjectId:
我們知道在mongo中insert操作是沒有返回值的,但有些業務場景又需要拿到insert后的id,那我們改怎么辦呢?
我們發現mongo的update操作有返回值,所以可以用update代替insert來獲取ObjectId,以完成上述的業務場景。
db.users.update( {'':''}, {'username':'zd'}, {'upsert':true} )
更新操作的原子性:
mongo的所有更新都是原子的,所有的寫操作都有鎖;2.2版本之前是實例級別,2.2之后是數據庫級別,3.0+為文檔級別。
原子性更新的語法:
db.collectionName.findAndModify({ query:{}, updae:{}, remove:true|false, new:true|false, sort:{}, fields:{}, upsert:true|false })
參數解釋:
1、query:查詢選擇器
2、update:要更新的值,不能與remote同時出現
3、remove:刪除符合query條件的文檔,不能與update同時出現
4、new:true=返回更新后的文檔,false=返回更新前的文檔;默認false
5、sort:排序條件
6、fields:投影操作,與find操作的第二個參數一致
7、upsert:與update的upsert參數一致,但它不僅會插入update的內容,還會插入query的內容