- MongoDB CRUD 操作 >
- 更新文档
更新文档¶
更新¶
MongoDB提供如下方法更新集合中的文档:
db.collection.updateOne() | 即使可能有多个文档通过过滤条件匹配到,但是也最多也只更新一个文档。 3.2 新版功能. |
db.collection.updateMany() | 更新所有通过过滤条件匹配到的文档. 3.2 新版功能. |
db.collection.replaceOne() | 即使可能有多个文档通过过滤条件匹配到,但是也最多也只替换一个文档。 3.2 新版功能. |
db.collection.update() | 即使可能有多个文档通过过滤条件匹配到,但是也最多也只更新或者替换一个文档。 默认情况下, db.collection.update() 只更新 一个 文档。要更新多个文档,请使用 multi 选项。 |
这些方法接收(如下)参数:
行为表现¶
_id 字段¶
一旦设定,你不能更新 _id 字段的值,你也不能用有不同 _id 字段值的替换文档来替换已经存在的文档。
文档大小¶
当执行更新操作增加的文档大小超过了为该文档分配的空间时。更新操作会在磁盘上重定位该文档。
字段顺序¶
MongoDB按照文档写入的顺序整理文档字段,除了 如下的情况:
_id 字段始终是文档中的第一个字段。
包括字段名称的 renaming 操作可能会导致文档中的字段重新排序。
在 2.6 版更改: 从2.6版本开始,MongoDB主动尝试保持字段在文档中的顺序。 2.6版本之前,MongoDB不会主动保持文档中的字段的顺序。
Upsert 选项¶
如果 db.collection.update(),db.collection.updateOne(), db.collection.updateMany() 或者 db.collection.replaceOne() 包含 upsert : true 并且 没有文档匹配指定的过滤器,那么此操作会创建一个新文档并插入它。如果有匹配的文档,那么此操作修改或替换匹配的单个或多个文档。
更多关于新文档创建的细节,请参考该方法的详细页。
示例集合¶
本页示例使用 mongo shell 中的 db.collection.find() 方法。在 mongo shell 中,如果返回的游标没有赋给使用 var 关键字的变量,那么该游标会自动迭代20次 [1] 来打印出结果中的前20个文档。
要添加示例中涉及的 users 集合,在 mongo shell中运行如下命令:
注解
如果 users 集合中已经包含了相同 _id 值的文档,你需要在插入示例文档前 drop 该集合( 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 提供了 update operators,例如用来修改值的 $set
为了用update操作执行指定的修改操作,可以使用如下更新文档的形式。
{
<update operator>: { <field1>: <value1>, ... },
<update operator>: { <field2>: <value2>, ... },
...
}
像:update:$set`这样的更新操作符,如果字段不存在则会创建字段。具体参考手册 :manual:`update operator</reference/operator/update>
db.collection.updateOne()¶
3.2 新版功能.
下面的例子对 users 集合使用 db.collection.updateOne() 方法来更新*第一个* 根据 过滤条件``favorites.artist`` 等于 "Picasso" 匹配到的文档更新操作:
使用 $set 操作符更新 favorites.food 字段的值为 "pie" 并更新 type 字段的值为 3,
使用 $currentDate 操作符更新 lastModified 字段的值到当前日期。如果 lastModified 字段不存在, $currentDate 会创建该字段。详情请参阅 $currentDate.
db.users.updateOne(
{ "favorites.artist": "Picasso" },
{
$set: { "favorites.food": "pie", type: 3 },
$currentDate: { lastModified: true }
}
)
更多信息和例子请参考 db.collection.updateOne()。
db.collection.updateMany()¶
3.2 新版功能.
下面的例子对 users 集合使用 db.collection.updateMany() 方法来更新所有根据过滤条件 favorites.artist 等于 "Picasso" 匹配的文档。更新操作:
使用 $set 操作符更新 favorites.food 字段的值为 "Pisanello" 并更新 type 字段的值为 3,
使用 $currentDate 操作符更新 lastModified 字段的值到当前日期。如果 lastModified 字段不存在, $currentDate 会创建该字段。详情请参阅 $currentDate.
db.users.updateMany(
{ "favorites.artist": "Picasso" },
{
$set: { "favorites.artist": "Pisanello", type: 3 },
$currentDate: { lastModified: true }
}
)
更多信息和例子请参考: db.collection.updateMany()。
db.collection.update¶
下面的例子对 users 集合使用 db.collection.update() 方法来更新根据过滤条件 favorites.artist 等于 "Pisanello" 匹配的 第一个 文档。更新操作:
使用 $set 操作符把 favorites.food 字段值更新为 "pizza" 并且把 type 字段的值更新为 0。
使用 $currentDate 操作符更新 lastModified 字段的值到当前日期。如果 lastModified 字段不存在, $currentDate 会创建该字段。详情请参阅 $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: 0, },
$currentDate: { lastModified: true }
},
{ multi: true }
)
文档替换¶
要更新除 _id 字段外文档的整个内容,传递一个全新的文档给 db.collection.replaceOne() 或者 db.collection.update() 作为第二个参数。当替换文档时,替换的文档必须仅仅由 <field> : <value> 组成.
替换文档可以有不同于原文档的字段。在替换文档中,由于 _id 字段是不变的,所以,你可以省略 _id 字段;不论如何,如果你包含了 _id 字段,它的值必须和当前的值相同。
db.collection.replaceOne¶
下面的例子对 users 集合使用 db.collection.replaceOne() 方法将通过过滤条件 name 等于 "sue" 匹配到的 第一个 文档替换为新文档:
db.users.replaceOne(
{ name: "abc" },
{ name: "amy", age: 34, type: 2, status: "P", favorites: { "artist": "Dali", food: "donuts" } }
)
db.collection.update¶
下面的例子对 users 集合使用 db.collection.update() 方法将通过过滤条件 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写操作要求的确认级别。详情请参见 Write Concern。
[1] | 你可以使用``DBQuery.shellBatchSize`` 来改变迭代结果的数量,默认是展示20条记录。 更多信息请参考 使用``mongo`` Shell。 |