前言
此篇博文是 Mongdb 基础系列之一;
本文为作者的原创作品,转载需注明出处;
简介
本文将会介绍如何使用下述方法通过 mongo shell 对文档进行 update 操作;1
2
3+ db.collection.updateOne(<filter>, <update>, <options>)
+ db.collection.updateMany(<filter>, <update>, <options>)
+ db.collection.replaceOne(<filter>, <replacement>, <options>)
为了演示本章的功能,假设我们有如下的测试用例,
1 | db.inventory.insertMany( [ |
Update Document in a Collection
MongoDB 提供了相关的 update operators,
Update a Single Document
1 | db.inventory.updateOne( |
上述方法使用 db.inventory.updateOne() 方法对 inventory collection 的第一个
item 元素等于 paper 的 document 进行更新操作;上面的更新操作对匹配的 document 执行如下的操作,
- 使用 $set 操作将 size.uom 字段的值更新为 “cm” 以及将 status 字段的值更新为 “P”,
- 使用 $currentDate 操作符将字段 lastModified 更新为当前日期;如果 lastModified 字段不存在,$currentDate 将会创建该字段;
需要注意的是
,updateOne() 方法的第一个参数值是匹配条件;
Update Multiple Documents
New in version 3.2.
下面的这个例子使用 db.collection.updateMany() 方法对 inventory collection 进行更新操作,匹配的条件是 qty 的值小于 50;
1 | db.inventory.updateMany( |
对匹配的 documents 进行的相关操作如下,
- 使用 $set 操作符将相关的 documents 的 size.uom 字段的值更新为 “in” 同时将 status 字段的值更新为 “P”,
- 使用 $currentDate 操作符将字段 lastModified 更新为当前日期;如果 lastModified 字段不存在,$currentDate 将会创建该字段;
这里与 Update a Single Document 的唯一的区别是,这里是一次性对所有匹配的文档做更新操作而不是匹配的第一个 document;
Replace a Document
如果是要替换整个文档内容,除了 _id 字段,那么只需要将新的文档作为第二个参数调用 db.collection.replaceOne() 方法即可;
需要注意的是,用来替换旧有 document 的新 document 可以拥有与旧 document 不相同的字段,在新的 document 中,你可以省略掉 _id 字段,因为 _id 字段是不可变的;不过,如果你坚持要传入 _id 字段,那么必须保证当前 document 与旧有的 document 的 _id 值必须相同;
下面这个例子将会使用新的 document 替换第一个匹配 filter condition { item: “paper” } 的原有 document,
1 | db.inventory.replaceOne( |
这里要特别注意
的是第二个参数,是一个新的,完整的 document 内容,
1 | { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] } |
特性
Atomicity
All write operations in MongoDB are atomic on the level of a
single document
. For more information on MongoDB and atomicity, see Atomicity and Transactions.
_id Field
Once set, you cannot update the value of the
_id
field nor can you replace an existing document with a replacement document that has a different_id
field value.
一句话就是,如果 _id 一旦设置,无论如何也不能被修改了,不管是对其进行 udpate 操作还是 replace 操作;
Document Size
When performing update operations that increase the document size
beyond
the allocated space for that document, the update operationrelocates
the document on disk.
当更新操作使得文档增大且超过了为其分配的空间,那么将会进行重新分配,分配到新的磁盘上;
Field Order
MongoDB 将会保留写入文档的字段顺序,不过 _id 例外,_id 始终是排在最前面,
这个特性是在 Version 2.6 和之后加入的,Version 2.6 以前 MongoDB 并不会保留文档字段的顺序;
Upsert 选项
如果在执行 updateOne(), updateMany(), 或者 replaceOne() 操作的时候,添加了选项 Upsert : true
,并且如果没有任何文档匹配了更新的条件,那么该更新操作将会创建一个新的 document 并插入到当前的 collection 中;如果匹配了更新的条件,那么还是按照原来的逻辑进行操作;
Write Acknowledgement
With write concerns, you can specify the level of acknowledgement requested from MongoDB for write operations. For details, see Write Concern.