iT邦幫忙

2021 iThome 鐵人賽

DAY 8
0
Software Development

MongoDB披荊斬棘之路系列 第 8

DAY8 MongoDB 批次操作(bulk wirte) 與 Operators

DAY8 MongoDB 批次操作(bulk wirte) 與 Operators

bulk write

bulk write 乍聽以為是批量寫入資料,想了一下好像也說得通,但是 MongoDB 包含了更多各種操作,可以在一個指令內包含 Insert, Update, Delete 等動作,所以可以做更多事情,但千萬要記得各個指令別互相打架啊....

先來看看 bulkWrite 長相:

db.collection.bulkWrite(
   [ <operation 1>, 
     <operation 2>, 
     ... 
   ],
   {
      writeConcern : <document>,
      ordered : <boolean>
   }
)

測試資料內容:

{ _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)
db.upsert2.demo.bulkWrite([
  { deleteOne: { 
      "filter" : {'name':'ErrorName'} } 
  },
  { updateOne: { 
      "filter" : {'name':'Arthas'}, 
      "update" : { $set: {'name':'Jaina'} } } 
  },
  { insertOne: { 
      "document" : {'name':'Uther', 'class':'Paladin'} } 
  }
],
  { ordered: false }
);

執行結果:

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 特別列出來,是因為效能不彰,官方也不建議使用。

  • $and / $or
  • $not / $nor

以上兩組四種就是程式常用的比較運算子。

  • $all: 查詢陣列內的值都全都符合指定內容
[
  { arr: [a,b,c,d,e] },
  { arr: [a,e] },
  { arr: [b,c,d,e] },
  { arr: [a,b,c,d] }
]

查詢 { arr: { $all : [a,e] } } 會得到

[
  { arr: [a,b,c,d,e] },
  { arr: [a,e] }
]

(沒特別加上字串單引號)

  • $elemMatch: 就是針對陣列內的值進行查詢
  • $size: 取得陣列的 size

上面三種為 Array 型別欄位專用的運算子。

  • $exists: 指定欄位是否存在

我們測試資料有這些,想要找出 class 欄位存在的資料,就會這樣操作:

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>

查詢用的 operator 大致介紹到這邊,明天來看如何進行查詢。


本系列文章會同步發表於我個人的部落格 Pie Note


上一篇
DAY7 MongoDB 資料更新(Update)
下一篇
DAY9 MongoDB 文件與嵌入式(巢狀)文件查詢(Find)
系列文
MongoDB披荊斬棘之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言