2021 iThome 鐵人賽 MongoDB披荊斬棘之路
DAY8 MongoDB 批次操作(bulk wirte) 與 Operators
bulk write
bulk write 乍聽以為是批量寫入資料,想了一下好像也說得通,但是 MongoDB 包含了更多各種操作,可以在一個指令內包含 Insert, Update, Delete 等動作,所以可以做更多事情,但千萬要記得各個指令別互相打架啊….
先來看看 bulkWrite 長相:
1 2 3 4 5 6 7 8 9 10
| db.collection.bulkWrite( [ <operation 1>, <operation 2>, ... ], { writeConcern : <document>, ordered : <boolean> } )
|
我們就先來看看測試資料有什麼內容:
1 2 3 4 5 6 7 8
| { _id: ObjectId("61310798630faf5d23c909d3"), name: 'ErrorName' }, { _id: ObjectId("61310798630faf5d23c909d4"), name: 'Arthas' }, { _id: ObjectId("61310798630faf5d23c909d5"), name: 'Arthas' }, { _id: ObjectId("61310798630faf5d23c909d6"), name: 'NewThrall', type: 'melee' }
|
這次目標就來:
- 刪除
ErrorName
(delete)
- 將一個
Arthas
改名為 Jaina
(update)
- 寫入一筆新資料 (insert)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| db.upsert2.demo.bulkWrite([ { deleteOne: { "filter" : {'name':'ErrorName'} } }, { updateOne: { "filter" : {'name':'Arthas'}, "update" : { $set: {'name':'Jaina'} } } }, { insertOne: { "document" : {'name':'Uther', 'class':'Paladin'} } } ], { ordered: false } );
|
執行結果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| film> db.upsert.demo2.bulkWrite([ { deleteOne: { "filter": { 'name': 'ErrorName' } } }, { updateOne: { "filter": { 'name': 'Arthas' }, "update": { $set: { 'name': 'Jaina' } } } }, { insertOne: { "document": { 'name': 'Uther', 'class': 'Paladin' } } }], { ordered: false }); { acknowledged: true, insertedCount: 1, insertedIds: { '0': ObjectId("61339d7e630faf5d23c909d8") }, matchedCount: 1, modifiedCount: 1, deletedCount: 1, upsertedCount: 0, upsertedIds: {} } film> db.upsert.demo2.find() [ { _id: ObjectId("61310798630faf5d23c909d4"), name: 'Jaina' }, { _id: ObjectId("61310798630faf5d23c909d5"), name: 'Arthas' }, { _id: ObjectId("61310798630faf5d23c909d6"), name: 'NewThrall', type: 'melee' }, { _id: ObjectId("61339d7e630faf5d23c909d8"), name: 'Uther', class: 'Paladin' } ]
|
坦白說我覺得語法實在不是很好記XD
ordered
ordered
參數預設值為 true
。
ordered 意思是指批次命令內,是否要由上到下依序執行,個人建議除非特殊需求或情境,否則依率將此參數設為 false
。依照官網描述,設定為 false
,有可能會使效能提升,衝著這點都值得了,但確實會有多少提升數據,並沒有特別提到實驗結果,畢竟每個條件和狀況都不同,難以概括定論。
{ ordered: false }
以後幾乎都會看到它。
查詢用的 Operators
MongoDB 的運算子很豐富,所以一些很明確的我就不多做解釋了。
- $gt / $gte: Greater than / Greater than or equal
- $lt / $lte: Less than / Less than or equal
- $eq: Euqal
- $in: 欄位存在於陣列內的任意值
- $ne: Not euqal
- $nin: Non in
會把 $ne
與 $nin
特別列出來,是因為效能不彰,官方也不建議使用。
以上兩組四種就是程式常用的比較運算子。
1 2 3 4 5 6
| [ { arr: [a,b,c,d,e] }, { arr: [a,e] }, { arr: [b,c,d,e] }, { arr: [a,b,c,d] } ]
|
查詢 { arr: { $all : [a,e] } }
會得到
1 2 3 4
| [ { arr: [a,b,c,d,e] }, { arr: [a,e] } ]
|
(沒特別加上字串單引號)
- $elemMatch: 就是針對陣列內的值進行查詢
- $size: 取得陣列的 size
上面三種為 Array 型別欄位專用的運算子。
我們測試資料有這些,想要找出 class
欄位存在的資料,就會這樣操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| film> db.upsert.demo2.find() [ { _id: ObjectId("61310798630faf5d23c909d4"), name: 'Jaina' }, { _id: ObjectId("61310798630faf5d23c909d5"), name: 'Arthas' }, { _id: ObjectId("61310798630faf5d23c909d6"), name: 'NewThrall', type: 'melee' }, { _id: ObjectId("61339d7e630faf5d23c909d8"), name: 'Uther', class: 'Paladin' } ] film> db.upsert.demo2.find({'class': {$exists: true}}) [ { _id: ObjectId("61339d7e630faf5d23c909d8"), name: 'Uther', class: 'Paladin' } ] film>
|