英文原文地址:https://docs.mongodb.com/v3.2/tutorial/update-documents/。
本文章属个人翻译,作个人学习之用,如有雷同,纯属巧合。如有错误之处,欢迎指正。
更新文档
Update
MongoDB提供了以下方法更新集合中的文档:
db.collection.updateOne() | 最多更新匹配到指定过滤器的的一个文档,即使多个文档匹配过滤器。版本3.2新增。 |
---|---|
db.collection.updateMany() | 更新匹配过滤器的所有文档。 版本3.2新增 |
db.collection.replaceOne() | 最多替换匹配到指定过滤器的的一个文档,即使多个文档匹配过滤器。 版本3.2新增。 |
db.collection.update() | 更新或替换匹配过滤器的一个文档,或者更新匹配的所有文档。 db.collection.update() 方法默认更新单个文档。要更新多个文档,使用 mutil 选项 |
这些方法接受如下参数:
一个过滤器文档来确定更新那些文档。这些过滤器使用同读操作一样的语法:
查询过滤文档
可以用<field>:<value>
表达式来指定相等条件,选择所有<field>
字段等于<value>
的文档:
{ <field1>: <value1>, ... }
查询过滤文档
可以用查询操作符来指定条件,形式如下:
{ <field1>: { <operator1>: <value1> }, ... }
一个更新文档来指定要执行的更新操作,或一个替换文档来替换整个匹配的文档,_id字段除外。
一个选项文档。
行为
原子
MongoDB中,在单个文档级别,所有的写操作都是原子的。参考原子与事务获得关于MongoDB和原子的更多信息。
_id字段
一旦_id字段设置了,不能更新_id字段的值,也不能用一个有不同_id字段值的替换文档来替换一个已经存在的文档。
文档大小
当更新操作使得文档的大小超出分配的大小时,会在硬盘上重新给该文档分配空间。
字段顺序
跟写操作一样,MongoDB会保持文档中字段的原有顺序,下面的情形除外:
- _id字段总是文档中的第一个字段
- 包含重命名字段的更新会导致文档中的字段重新排序
版本2.6的改动:自版本2.6开始,MongoDB总是会试图保持文档中字段的顺序。在2.6之前,不会这么做。
Upsert选项
若db.collection.update()
,db.collection.updateOne()
,db.collection.updateMany()
,或db.collection.replaceOne()
含有upsert:true
选项,并且没有文档匹配到指定的过滤器,则该操作会创建一个新的文档并插入。如果有匹配的文档,则该操作只会修改或替换所匹配的文档。
示例集合
为填充本例子中所提到的users
集合,请在mongo
shell中运行一下代码:
注意
如果
users
集合已经包含了相同_id的集合,插入文档前需要删除该集合(db.users.drop()
)
db.users.insertMany( [ { _id: 1, name: "sue", age: 19, type: 1, status: "P", favorites: { artist: "Picasso", food: "pizza" }, finished: [ 17, 3 ], badges: [ "blue", "black" ], points: [ { points: 85, bonus: 20 }, { points: 85, bonus: 10 } ] }, { _id: 2, name: "bob", age: 42, type: 1, status: "A", favorites: { artist: "Miro", food: "meringue" }, finished: [ 11, 25 ], badges: [ "green" ], points: [ { points: 85, bonus: 20 }, { points: 64, bonus: 12 } ] }, { _id: 3, name: "ahn", age: 22, type: 2, status: "A", favorites: { artist: "Cassatt", food: "cake" }, finished: [ 6 ], badges: [ "blue", "Picasso" ], points: [ { points: 81, bonus: 8 }, { points: 55, bonus: 20 } ] }, { _id: 4, name: "xi", age: 34, type: 2, status: "D", favorites: { artist: "Chagall", food: "chocolate" }, finished: [ 5, 11 ], badges: [ "Picasso", "black" ], points: [ { points: 53, bonus: 15 }, { points: 51, bonus: 15 } ] }, { _id: 5, name: "xyz", age: 23, type: 2, status: "D", favorites: { artist: "Noguchi", food: "nougat" }, finished: [ 14, 6 ], badges: [ "orange" ], points: [ { points: 71, bonus: 20 } ] }, { _id: 6, name: "abc", age: 43, type: 1, status: "A", favorites: { food: "pizza", artist: "Picasso" }, finished: [ 18, 12 ], badges: [ "black", "blue" ], points: [ { points: 78, bonus: 8 }, { points: 57, bonus: 7 } ] } ] )
更新文档中的指定字段
要修改文档的一个字段,MongoDB提供了更新操作符,如$set
。
要指定执行的修改,使用格式如下:
{
<update operator>: { <field1>: <value1>, ... },
<update operator>: { <field2>: <value2>, ... },
...
}
有些更新操作符,如$set
,当字段不存在时会创建该字段。参考更新操作符。
db.collection.updateOne()
版本3.2新增。
下面的例子使用db.collection.updateOne()
方法,在users
集合上更新第一个匹配”favorites.artist”等于”Picasso”的文档。该操作:
- 用
$set
操作符把favorites.food
字段的更新为"pie",把
type的值更新为
3` - 用
$currentDate
操作符把lastModified
的值更新为当前日期。如果lastModified
字段不存在,$currentDate
会创建该字段。
db.users.updateOne(
{ "favorites.artist": "Picasso" },
{
$set: { "favorites.food": "pie", type: 3 },
$currentDate: { lastModified: true }
}
)
更多信息和例子,请查看db.collection.updateOne()。
db.collectioin.updateMany()
版本3.2新增。
下面的例子使用db.collection.updateMany()
方法,在users
集合上更新所有匹配”favorites.artist”等于”Picasso”的文档。该操作:
- 用
$set
操作符把favorites.artist
字段的更新为"Pisanello",把
type的值更新为
3` - 用
$currentDate
操作符把lastModified
zi’d的值更新为当前日期。如果lastModified
字段不存在,$currentDate
会创建该字段。
db.users.updateMany(
{ "favorites.artist": "Picasso" },
{
$set: { "favorites.artist": "Pisanello", type: 3 },
$currentDate: { lastModified: true }
}
)
更多信息和例子,请查看db.collection.updateMany()。
db.collection.update()
下面的例子使用db.collection.update()
方法,在users
集合上更新第一个匹配”favorites.artist”等于”Pisanello”的文档。该操作:
- 用
$set
操作符把favorites.food
字段的更新为"pizza"
,把type
的值更新为0
- 用
$currentDate
操作符把lastModified
的值更新为当前日期。如果lastModified
字段不存在,$currentDate
会创建该字段。
db.users.update(
{ "favorites.artist": "Pisanello" },
{
$set: { "favorites.food": "pizza", type: 0 },
$currentDate: { lastModified: true }
}
)
要更新多个文档,在db.collection.update()
中使用multi:true
选项:
db.users.update(
{ "favorites.artist": "Pisanello" },
{
$set: { "favorites.food": "pizza", type: 3 },
$currentDate: { lastModified: true }
},
{ multi: true }
)
替换文档
要替换除_id字段的整个文档的内容,把全新的整个文档作为第二个参数传给db.collection.replaceOne()
或者db.collection.update()
。替换文档时,替换文档只能有<field>:<value>
组成。
替换文档可用与有原文档不同的字段。在替换文档中,可用忽略_id字段,因为_id字段是不可变的,你也可以包含_id字段,不过必须与原来的值一样。
db.collection.replaceOne()
以下例子使用db.collection.replaceOne()
方法,在users
集合上用新文档替换第一个匹配name
字段等于”abc”的文档:
db.users.replaceOne(
{ name: "abc" },
{ name: "amy", age: 34, type: 2, status: "P", favorites: { "artist": "Dali", food: "donuts" } }
)
db.collection.update()
以下例子使用db.collection.update()
方法,在users
集合上用新文档替换第一个匹配name
字段等于”xyz”的文档:
db.users.update(
{ name: "xyz" },
{ name: "mee", age: 25, type: 1, status: "A", favorites: { "artist": "Matisse", food: "mango" } }
)
其它方法
以下方法也可以用来更新集合中的文档:
db.collection.findOneAndReplace()
db.collection.findOneAndUpdate()
db.collection.findAndModify()
db.collection.save()
db.collection.bulkWrite()
写确认
通过写确认,可用指定写操作从MongoDB返回的确认级别。