MongDB 更新
基本
语法
db.collection.update(query, update, options)
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string>, // Added in MongoDB 4.2
let: <document> // Added in MongoDB 5.0
}
)
-
query:查询条件
-
update:要更新的对象和一些更新操作符
-
字段
操作符 语法 含义 $set { $set: { : , ... } } 用指定的值替换字段的值。 $inc { $inc: { : , : , ... } } 将字段按指定值递增 $unset { $unset: { : , ... } } 删除一个特定的字段。 $rename {$rename: { : , : , ... } } 更新字段的名称 $min { $min: { : , ... } } 仅当指定值小于现有字段值时才更新该字段。如果该字段不存在,则将字段设置为指定的值。 $currentDate { $currentDate: { : , ... } } 将字段的值设置为当前日 期,可以是date,也可以是timestamp。默认类型为Date。 $max { $max: { : , ... } } 仅当指定值大于现有字段值时才更新该字段。如果该字段不存在,则将字段设置为指定的值。 $mul { $mul: { : , ... } } 将字段的值乘以一个数字 $setOnInsert 在upsert过程中,在创建文档时设置字段的值。 对修改现有文档的更新操作没有影响。 -
数组
操作符 含义 $ 标识数组中要更新的元素,而不显式指定元素在数组中的位置。(有时候你根本不知道元素具体位置;见案例篇) $[] 充当占位符,为匹配查询条件的文档更新数组中的所有元素。 $[ ] 充当占位符,为匹配查询条件的文档更新与arrayFilters条件匹配的所有元素。 $addToSet 仅在集合中不存在元素时才将元素添加到数组中。 $push 向已有数组末尾追加元素,要是不存在就创建一个数组。 $pop 删除数组中的数据;1表示从comments数组的末尾删除一条数据,-1表示从comments数组的开头删除一条数据。 $pull 按条件删除数组中的某个元素 $pullAll 按条件删除数组中的全部元素 -
修饰符
操作符 含义 $each 将多个值追加到数组字段; $position 限制数组元素的数量。配合$each使用; $slice 对数组中的元素排序。配合$each使用; $sort 指定插入元素的位置。配合$each使用。
-
-
options:额外选项
-
upsert:bool,若不存在 query 的记录时,是否插入新的文档
db.books.update(
{ item: "ZZZ135" }, // Query parameter
{ // Replacement document
item: "ZZZ135",
stock: 5,
tags: [ "database" ]
} ,
{ upsert: true } // Options
) -
multi:bool,是否更新所有符合查询条件的记录,默认 false
db.books.update(
{ stock: { $lte: 10 } },
{ $set: { reorder: true } },
{ multi: true }
) -
writeConcern:写入安全机制,用于控制写入安全的级别。它指定了在写操作完成之前,MongoDB需要接收到的确认数。writeConcern级别越高,写操作的确认就越安全,但也会影响写的性能。
- writeConcern有三种级别,分别是
- 1:表示写操作需要写入主节点的内存中,但不需要确认写操作是否成功。这是默认级别。
- majority:表示写操作需要写入大多数节点的内存中,并且需要确认写操作是否成功。
<number>:表示写操作需要写入指定数量的节点的内存中,并且需要确认写操作是否成功。
- writeConcern有三种级别,分别是
-
arrayFilters
-
用于更新嵌套数组中满足指定条件的元素。它可以在更新语句中使用,以指定需要更新的嵌套数组元素的条件。
-
arrayFilters 可以包含多个条件,每个条件都是一个对象,用于指定需要更新的数组元素的查询条件。
db.collection.update(
{ <query conditions> },
{ <update operator>: { "<array>.$[<identifier>]" : value } },
{ arrayFilters: [ { <identifier>: <condition> } ] }
)
// <identifier> 用来充当数组字段中与 arrayFilters 中指定的条件匹配的所有元素的占位符,必须以小写字母开头,且只能包含字母数字字符。db.students.insertMany( [
{ "_id" : 1, "grades" : [ 95, 92, 90 ] },
{ "_id" : 2, "grades" : [ 98, 100, 102 ] },
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }
] )
db.students.updateMany(
{ },
{ $set: { "grades.$[element]" : 100 } },
{ arrayFilters: [ { "element": { $gte: 100 } } ] }
)
-
-
返回:WriteResult
- 执行成功时
- nMatched:匹配查询条件的文档数量
- nUpserted:更新插入的文档数量
- nModified:修改的文档数量
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
- 执行失败时
- 除了成功哪些字段之外,还包含writeConcernError
WriteResult({
"nMatched" : 1,
"nUpserted" : 0,
"nModified" : 1,
"writeConcernError": {
"code" : 64,
"errmsg" : "waiting for replication timed out",
"errInfo" : {
"wtimeout" : true,
"writeConcern" : {
"w" : "majority",
"wtimeout" : 100,
"provenance" : "getLastErrorDefaults"
}
}
})
更新操作符
字段更新操作符
$se
用来修改指定字段的值;如果指定字段不存在,则创建它。
{ $set: { <field1>: <value1>, ... } }
用例
db.products.insertOne(
{
_id: 100,
quantity: 250,
instock: true,
reorder: false,
details: { model: "14QQ", make: "Clothes Corp" },
tags: [ "apparel", "clothing" ],
ratings: [ { by: "Customer007", rating: 4 } ]
}
)
更新普通字段/嵌套字段
db.products.updateOne(
{ _id: 100 },
{ $set:
{
quantity: 500,
details: { model: "2600", make: "Fashionaires" },
tags: [ "coats", "outerwear", "clothing" ],
"details.make": "Kustom Kidz"
}
}
)
更新数组字段(按索引)
db.products.updateOne(
{ _id: 100 },
{ $set:
{
"tags.1": "rain gear",
"ratings.0.rating": 2
}
}
)
如果是要按条件更新的话,就用 arrayFilter 吧
$inc
用来增加已有键的值
{ $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }
用例
db.products.insertOne(
{
_id: 1,
sku: "abc123",
quantity: 10,
metrics: { orders: 2, ratings: 3.5 }
}
)
db.products.update(
{ sku: "abc123" },
{ $inc: { quantity: -2, "metrics.orders": 1 } }
)
$rename
用于更新字段的名称,新字段的名字不能与已有的字段名字重名;如果要修改嵌入文档名称使用 .
db.students.update({}, { $rename: { "nmae": "name" } }, { multi: true })
// or
db.students.updateMany({}, { $rename: { "nmae": "name" } })
$unset
用于删除特定字段
{ $unset: { <field1>: "", ... } }
删除 sku=unknown 中的 quantity 和 instock 字段
db.products.update(
{ sku: "unknown" },
{ $unset: { quantity: "", instock: "" } }
)
数组更新操作符
添加字段
$addToSet
如果元素不存在数组中则添加,如果存在则不添加;可使用 $each 修饰来添加多个元素。
{ $addToSet: { <field1>: <value1>, ... } }
用例
db.inventory.insertOne(
{ _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera" ] })
添加单个元素
db.inventory.updateOne(
{ _id: 1 },
{ $addToSet: { tags: "accessories" } }
)
用 $each 添加多个元素
db.inventory.updateOne(
{ _id: 2 },
{ $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } }
)
$push
添加指定值到数组中,可重复。可修饰符有:
$each: 将多个值追加到数组字段$slice: 限制数组元素的数量。配合$each使用$sort:对数组中的元素排序。配合$each使用$position:指定插入元素的位置。配合$each使用。若为空,则默认添加到末尾。
{ $push: { <field1>: <value1>, ... } }
用例
db.students.insertOne( { _id: 1, scores: [ 44, 78, 38, 80 ] } )
db.students.updateOne(
{ _id: 1 },
{ $push: { scores: 89 } }
)
添加多个值
db.students.updateOne(
{ name: "joe" },
{ $push: { scores: { $each: [ 90, 92, 85 ] } } }
)
使用多个修饰符。用例
db.students.insertOne(
{
"_id" : 5,
"quizzes" : [
{ "wk": 1, "score" : 10 },
{ "wk": 2, "score" : 8 },
{ "wk": 3, "score" : 5 },
{ "wk": 4, "score" : 6 }
]
}
)
下面的语句首先添加 { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } 到 quizzes 中,然后根据 score 进行降序排序,最后保留前三个元素
db.students.updateOne(
{ _id: 5 },
{
$push: {
quizzes: {
$each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ],
$sort: { score: -1 },
$slice: 3
}
}
}
)