mongoose之bulkWrite操作使用實(shí)例
前言
在執(zhí)行mongo操作時(shí),有時(shí)候大家會(huì)覺(jué)得力不從心,比如:要給大量的數(shù)據(jù)更新,但是各個(gè)數(shù)據(jù)更新的內(nèi)容不一樣;需要批量創(chuàng)建大量數(shù)據(jù); 以上操作,如果單純使用findIOneAndUpdate或者save,首先是非常耗時(shí)、其次使用了大量的資源;
那么有沒(méi)有什么好的方法去替代呢?
mongoose提供了bulkWrite批量操作防范,這個(gè)方法支持批量插入、更新和刪除;
當(dāng)然,不會(huì)有人以為批量操作就不能單獨(dú)操作一條數(shù)據(jù)吧!
一: bulkWrite小小解釋
mongoose關(guān)于bulkWrite的原文:mongoosejs.com/docs/api.ht…
操作語(yǔ)法:
db.collection.bulkWrite(
[ <operation 1>, <operation 2>, ... ],
{
writeConcern : <document>,
ordered : <boolean>
}
)
| 參數(shù) | 類(lèi)型 | 是否必填 | 描述 |
|---|---|---|---|
| operations | array | 必填 | bulkWrite() 寫(xiě)操作的數(shù)組。支持操作:insertOne、updateOne、updateMany、deleteOne、deleteMany、replaceOne |
| writeConcern | document | 選填 | write concern 文檔,省略則使用默認(rèn)的 write concern,一般無(wú)用 |
| ordered | boolean | 選填 | 表示mongod實(shí)例有序還是無(wú)序執(zhí)行操作。默認(rèn)值true。 |
關(guān)于ordered
- 如果為true,有序執(zhí)行,按順序執(zhí)行并在第一個(gè)錯(cuò)誤處停止,遇到錯(cuò)誤就停止執(zhí)行后續(xù)的operations操作(后續(xù)的操作不會(huì)被執(zhí)行)
- 如果為false,無(wú)序執(zhí)行,為并行執(zhí)行,如果遇到錯(cuò)誤,會(huì)繼續(xù)執(zhí)行在一個(gè)操作,直到所有操作成功或出錯(cuò);
綜上所述,個(gè)人建議使用時(shí)配置為無(wú)序執(zhí)行;各位可以按需求使用,后續(xù)會(huì)具體說(shuō)明各項(xiàng)操作及返回值
二:具體操作
insertOne
插入單個(gè)文檔到集合中;
db.collection.bulkWrite( [
{ insertOne : { "document" : {} } },
{ insertOne : { "document" : {} } }
] ,{ordered:fasle})
db.collection.bulkWrite( [
{ insertOne : { "document" : {} } },
{ insertOne : { "document" : {} } }
])
字段說(shuō)明
insertOne.document:需要插入的文檔信息,如果文檔不包含_id,則會(huì)自動(dòng)生成;ordered:選填,有序還是無(wú)序執(zhí)行;
updateOne
updateOne 更新集合中 filter 匹配的單個(gè)文檔。如果匹配到多個(gè)文檔 updateOne 僅更新第一個(gè)匹配到的文檔;
db.collection.bulkWrite( [
{ updateOne :
{
"filter" : {name:"bulkWrite6"},
"update" : {$set:{age:19}},
"upsert" :true
}
}
],{ordered:fasle} )
db.collection.bulkWrite( [
{ updateOne :
{
"filter" : {name:"bulkWrite6"},
"update" : {$set:{age:19}},,
"upsert" :true
}
}
] )
字段說(shuō)明
updateOne.filter:object,必填,匹配條件;updateOne.update:object,必填,更新內(nèi)容,可執(zhí)行操作為:set、 set 、set、 unset 、$rename等等;updateOne.upsert: boolean, 選填,默認(rèn)為false,如果為true,則沒(méi)有匹配時(shí)插入一個(gè)新文檔;
updateMany
updateMany 更新集合中所有匹配到的文檔;
db.collection.bulkWrite( [
{ updateMany :
{
"filter" : {name:"bulkWrite6"},
"update" : {$set:{age:19}},
"upsert" :true
}
}
],{ordered:fasle} )
db.collection.bulkWrite( [
{ updateMany :
{
"filter" : {name:"bulkWrite6"},
"update" : {$set:{age:19}},,
"upsert" :true
}
}
] )
字段說(shuō)明
updateOne.filter:object,必填,匹配條件;updateOne.update:object,必填,更新內(nèi)容,可執(zhí)行操作為:set、 set 、set、 unset 、$rename等等;updateOne.upsert: boolean, 選填,默認(rèn)為false,如果為true,則插入一個(gè)文檔filter
deleteOne
deleteOne 刪除集合中 filter 匹配到的單個(gè)文檔。如果匹配到多個(gè)文檔 deleteOne 只會(huì)刪除一個(gè)匹配到的文檔;
db.collection.bulkWrite([
{ deleteOne : { "filter" : {age:19} } }
] )
字段說(shuō)明
deleteOne.filter:object,必填,刪除與此過(guò)濾器匹配的第一個(gè)文檔;
deleteMany
deleteMany 刪除集合中 filter 匹配到的所有文檔;
db.collection.bulkWrite([
{ deleteMany : { "filter" : {age:19} } }
] )
字段說(shuō)明
deleteMany.filter:object,必填,刪除與此過(guò)濾器匹配的所有文檔;
replaceOne
replaceOne 替換集合中 filter 匹配到的單個(gè)文檔。如果匹配到多個(gè)文檔 replaceOne 只會(huì)替換一個(gè)匹配到的文檔;
db.collection.bulkWrite([
{ replaceOne :
{
"filter" :{age:19},
"replacement" : {age:20},
"upsert" :true
}
}
] )
字段說(shuō)明
updateOne.filter:object,必填,替換與此過(guò)濾器匹配的第一個(gè)文檔;updateOne.update:object,必填,替換內(nèi)容;updateOne.upsert: boolean, 選填,默認(rèn)為false,如果為true,如果沒(méi)有匹配的文檔,則插入一個(gè)文檔filter
三:優(yōu)點(diǎn)
- 可以批量同時(shí)執(zhí)行不同的操作,新增、修改、刪除;
- 執(zhí)行速率比save、findOneAndUpdate等等快,因?yàn)?,bulkWrite是在一個(gè)命令中向 MongoDB 服務(wù)器發(fā)送多個(gè)insertOne、updateOne、updateMany、replaceOne、 deleteOne等等的請(qǐng)求,這比發(fā)送多個(gè)獨(dú)立操作更快,因?yàn)閎ulkWrite()只有一次往返 MongoDB,而每一次獨(dú)立操作都是一次往返的MongoDB。
四:以下需要注意
- ordered參數(shù),由于bulkWrite中可以幾個(gè)操作同時(shí)混合使用,那么,如果使用無(wú)序執(zhí)行時(shí),可能會(huì)造成deleteOne或deleteMany 刪除的文檔可能會(huì)變多或變少,具體取決于deleteOne或deleteMany 是在insertOne,updateOne,updateMany或replaceOne操作之前或之后的運(yùn)行。
如下:
db.collection.bulkWrite(
[
{ insertOne : <document> },
{ updateOne : <document> },
{ updateMany : <document> },
{ replaceOne : <document> },
{ deleteOne : <document> },
{ deleteMany : <document> }
],
{ ordered : false }
)
- 更新(updateOne、updateMany)或替換(replaceOne)操作不能指定與原始文檔不同的 _id 值;
五:錯(cuò)誤返回
錯(cuò)誤返回值主要分為兩種,ordered的有序和無(wú)序執(zhí)行的錯(cuò)誤返回, 以下述插入為例,第一項(xiàng)、第四項(xiàng)和第五項(xiàng)是不存在的,第二項(xiàng)和第三項(xiàng)的_id是已存在的
有序執(zhí)行錯(cuò)誤
db.collection.bulkWrite(
[
{
insertOne: { document: { name: 'bulkWrite10' } }
},
{
insertOne: { document: { _id: '6321a77b06e79133d99b926c', name: 'bulkWrite6' } }
},
{
insertOne: { document: { _id: '63227cde0795b55523c0e8ac', name: 'bulkWrite7' } }
},
{
insertOne: { document: { name: 'bulkWrite11' } }
},
{
insertOne: { document: { name: 'bulkWrite12' } }
}
],
{ ordered: true }
);
有序執(zhí)行錯(cuò)誤,返回值中只有一個(gè)錯(cuò)誤的,但是insertedIds中index=2、3、4都沒(méi)有執(zhí)行
{
"code": 11000,
"writeErrors": [
{
"code": 11000,
"index": 1,
"errmsg": "E11000 duplicate key error collection: test_one.users index: _id_ dup key: { _id: ObjectId('6321a77b06e79133d99b926c') }",
"op": {
"name": "bulkWrite6",
"age": 0,
"register_time": "2022-09-15T03:45:04.529Z",
"remark": null,
"vip": false,
"address": null,
"_id": "6321a77b06e79133d99b926c"
}
}
],
"result": {
"ok": 1,
"writeErrors": [
{
"code": 11000,
"index": 1,
"errmsg": "E11000 duplicate key error collection: test_one.users index: _id_ dup key: { _id: ObjectId('6321a77b06e79133d99b926c') }",
"op": {
"name": "bulkWrite6",
"age": 0,
"register_time": "2022-09-15T03:45:04.529Z",
"remark": null,
"vip": false,
"address": null,
"_id": "6321a77b06e79133d99b926c"
}
}
],
"writeConcernErrors": [],
"insertedIds": [
{
"index": 0,
"_id": "63229fc8afcdaac9bd268102"
},
{
"index": 1,
"_id": "6321a77b06e79133d99b926c"
},
{
"index": 2,
"_id": "63227cde0795b55523c0e8ac"
},
{
"index": 3,
"_id": "63229fc8afcdaac9bd268105"
},
{
"index": 4,
"_id": "63229fc8afcdaac9bd268106"
}
],
"nInserted": 1,
"nUpserted": 0,
"nMatched": 0,
"nModified": 0,
"nRemoved": 0,
"upserted": []
}
}
無(wú)序執(zhí)行錯(cuò)誤
db.collection.bulkWrite(
[
{
insertOne: { document: { name: 'bulkWrite10' } }
},
{
insertOne: { document: { _id: '6321a77b06e79133d99b926c', name: 'bulkWrite6' } }
},
{
insertOne: { document: { _id: '63227cde0795b55523c0e8ac', name: 'bulkWrite7' } }
},
{
insertOne: { document: { name: 'bulkWrite11' } }
},
{
insertOne: { document: { name: 'bulkWrite12' } }
}
],
{ ordered: false }
);
無(wú)序執(zhí)行錯(cuò)誤,返回值中有兩個(gè)報(bào)錯(cuò),三個(gè)插入成功
{
"code": 11000,
"writeErrors": [
{
"code": 11000,
"index": 1,
"errmsg": "E11000 duplicate key error collection: test_one.users index: _id_ dup key: { _id: ObjectId('6321a77b06e79133d99b926c') }",
"op": {
"name": "bulkWrite6",
"age": 0,
"register_time": "2022-09-15T03:47:51.976Z",
"remark": null,
"vip": false,
"address": null,
"_id": "6321a77b06e79133d99b926c"
}
},
{
"code": 11000,
"index": 2,
"errmsg": "E11000 duplicate key error collection: test_one.users index: _id_ dup key: { _id: ObjectId('63227cde0795b55523c0e8ac') }",
"op": {
"name": "bulkWrite7",
"age": 0,
"register_time": "2022-09-15T03:47:51.976Z",
"remark": null,
"vip": false,
"address": null,
"_id": "63227cde0795b55523c0e8ac"
}
}
],
"result": {
"ok": 1,
"writeErrors": [
{
"code": 11000,
"index": 1,
"errmsg": "E11000 duplicate key error collection: test_one.users index: _id_ dup key: { _id: ObjectId('6321a77b06e79133d99b926c') }",
"op": {
"name": "bulkWrite6",
"age": 0,
"register_time": "2022-09-15T03:47:51.976Z",
"remark": null,
"vip": false,
"address": null,
"_id": "6321a77b06e79133d99b926c"
}
},
{
"code": 11000,
"index": 2,
"errmsg": "E11000 duplicate key error collection: test_one.users index: _id_ dup key: { _id: ObjectId('63227cde0795b55523c0e8ac') }",
"op": {
"name": "bulkWrite7",
"age": 0,
"register_time": "2022-09-15T03:47:51.976Z",
"remark": null,
"vip": false,
"address": null,
"_id": "63227cde0795b55523c0e8ac"
}
}
],
"writeConcernErrors": [],
"insertedIds": [
{
"index": 0,
"_id": "6322a06b9145a56d3b23fabe"
},
{
"index": 1,
"_id": "6321a77b06e79133d99b926c"
},
{
"index": 2,
"_id": "63227cde0795b55523c0e8ac"
},
{
"index": 3,
"_id": "6322a06b9145a56d3b23fac1"
},
{
"index": 4,
"_id": "6322a06b9145a56d3b23fac2"
}
],
"nInserted": 3,
"nUpserted": 0,
"nMatched": 0,
"nModified": 0,
"nRemoved": 0,
"upserted": []
}
}
六:思考
個(gè)人經(jīng)常使用bulkWrite的場(chǎng)景是:
- 定時(shí)更新數(shù)據(jù),比如更新人員基本信息,因?yàn)槊總€(gè)人更新的內(nèi)容都不相同;
- 刷數(shù)據(jù),有些數(shù)據(jù)需要?jiǎng)h除、有些需要更新、有些需要新增;
bulkWrite是比save、update更為高級(jí)的寫(xiě)法,希望大家可以靈活運(yùn)用。
引用
mongoose關(guān)于bulkWrite的原文:mongoosejs.com/docs/api.ht…
以上就是mongoose之bulkWrite操作使用實(shí)例的詳細(xì)內(nèi)容,更多關(guān)于mongoose bulkWrite操作的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序?qū)崿F(xiàn)商品分類(lèi)頁(yè)過(guò)程結(jié)束
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)商品分類(lèi)頁(yè)列表方法,商品分類(lèi)頁(yè)主要是需要實(shí)現(xiàn)商品類(lèi)目和對(duì)應(yīng)商品標(biāo)題的聯(lián)動(dòng)跳轉(zhuǎn),文中過(guò)程詳細(xì),感興趣的小伙伴們可以參考一下2023-05-05
跟我學(xué)習(xí)javascript的prototype原型和原型鏈
跟我學(xué)習(xí)javascript的prototype原型和原型鏈,感興趣的小伙伴們可以參考一下2015-11-11
ECharts柱狀排名圖柱子上方顯示文字與圖標(biāo)代碼實(shí)例
我們?cè)诶L制柱狀圖時(shí)如果想要柱條上顯示文字,可以參考本文,這篇文章主要給大家介紹了關(guān)于ECharts柱狀排名圖柱子上方顯示文字與圖標(biāo)的相關(guān)資料,需要的朋友可以參考下2023-11-11
老生常談JavaScript 正則表達(dá)式語(yǔ)法
下面小編就為大家?guī)?lái)一篇老生常談JavaScript 正則表達(dá)式語(yǔ)法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08
javascript實(shí)現(xiàn)自由編輯圖片代碼詳解
這篇文章主要介紹了javascript實(shí)現(xiàn)自由編輯圖片代碼詳解,在當(dāng)下的的前端項(xiàng)目中,圖片功能可以說(shuō)是非常常見(jiàn)的,圖片的展示、圖片的裁剪編輯、圖片的上傳等,那么我們的項(xiàng)目便來(lái)了個(gè)需求。,需要的朋友可以參考下2019-06-06
js實(shí)現(xiàn)帶按鈕的上下滾動(dòng)效果
這篇文章主要介紹了js實(shí)現(xiàn)帶按鈕的上下滾動(dòng)效果,設(shè)計(jì)javascript鼠標(biāo)事件及頁(yè)面元素樣式的相關(guān)操作技巧,需要的朋友可以參考下2015-05-05
Canvas實(shí)現(xiàn)動(dòng)態(tài)粒子文字效果的代碼示例
這篇文章主要介紹了如何用Canvas實(shí)現(xiàn)動(dòng)態(tài)粒子文字效果,文中有完整的代碼示例,文章通過(guò)代碼介紹的非常清楚,感興趣的小伙伴跟著小編一起來(lái)看看吧2023-08-08
js實(shí)現(xiàn)表格拖動(dòng)選項(xiàng)
這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)表格拖動(dòng)選項(xiàng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04

