MongoDB學習筆記(三、MongoDB聚合與更新)


目錄:

  • 聚合
  • 更新
  • 更新選擇器
  • 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的內容


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM