$ (update)
在本页面
Definition
$
- 位置$运算符标识数组中要更新的元素,而无需显式指定该元素在数组中的位置。
Disambiguation
-
要从读取操作投影或返回数组元素,请参阅$投影运算符。
-
要更新数组中的所有元素,请参阅所有位置运算符$[]。
-
要更新所有符合一个或多个数组过滤条件的元素,请参阅过滤后的位置运算符$[<identifier>]。
位置$运算符的格式为:
{ "<array>.$" : value }
当用于更新操作时,例如db.collection.update()和db.collection.findAndModify(),
-
位置$运算符充当与
query document
匹配的 first 元素的占位符,并且 -
array
字段 必须 出现在query document
的一部分中。
For example:
db.collection.update(
{ <array>: value ... },
{ <update operator>: { "<array>.$" : value } }
)
Behavior
upsert
不要将位置运算符$与upsert操作一起使用,因为插入将使用$
作为插入文档中的字段名称。
Nested Arrays
位置$运算符不能用于遍历一个以上数组的查询,例如遍历嵌套在其他数组中的数组的查询,因为$占位符的替换是单个值
Unsets
当与$unset运算符一起使用时,位置$运算符不会从数组中删除匹配的元素,而是将其设置为null
。
Negations
如果查询使用否定运算符(例如$ne,$not或$nin)与数组匹配,则无法使用位置运算符从该数组更新值。
但是,如果查询的否定部分在$elemMatch表达式内,则您可以使用位置运算符来更新此字段。
Examples
更新数组中的值
创建包含以下文档的集合students
:
db.students.insert([
{ "_id" : 1, "grades" : [ 85, 80, 80 ] },
{ "_id" : 2, "grades" : [ 88, 90, 92 ] },
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }
])
要在grades
数组中将值80
的第一个元素更新为82
,请使用位置$运算符(如果您不知道该元素在数组中的位置):
Important
您必须将数组字段包含在query
文档中。
db.students.updateOne(
{ _id: 1, grades: 80 },
{ $set: { "grades.$" : 82 } }
)
位置$运算符充当更新query document的“首次匹配”的占位符。
操作完成后,students
集合包含以下文档:
{ "_id" : 1, "grades" : [ 85, 82, 80 ] }
{ "_id" : 2, "grades" : [ 88, 90, 92 ] }
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }
更新数组中的文档
位置$运算符有助于更新包含嵌入式文档的数组。使用位置$运算符和$运算符上的dot notation来访问嵌入文档中的字段。
db.collection.update(
{ <query selector> },
{ <update operator>: { "array.$.field" : value } }
)
请考虑students
集合中的以下文档,其grades
元素值是嵌入式文档的数组:
{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 85, mean: 85, std: 8 }
]
}
使用位置$运算符更新与grade
等于85
条件匹配的第一个数组元素的std
字段:
Important
您必须将数组字段包含在query
文档中。
db.students.updateOne(
{ _id: 4, "grades.grade": 85 },
{ $set: { "grades.$.std" : 6 } }
)
操作后,文档具有以下更新值:
{
"_id" : 4,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 8 },
{ "grade" : 85, "mean" : 90, "std" : 6 },
{ "grade" : 85, "mean" : 85, "std" : 8 }
]
}
使用多个字段匹配项更新嵌入式文档
$运算符可以更新与$elemMatch()运算符指定的多个查询条件匹配的第一个数组元素。
请考虑students
集合中的以下文档,其grades
字段值是嵌入式文档的数组:
{
_id: 5,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 90, mean: 85, std: 3 }
]
}
在下面的示例中,$运算符更新第一个嵌入式文档中具有grade
字段小于或等于90
的值和mean
字段具有大于80
的值的std
字段的值:
db.students.updateOne(
{
_id: 5,
grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } }
},
{ $set: { "grades.$.std" : 6 } }
)
此操作将更新符合条件的第一个嵌入式文档,即数组中的第二个嵌入式文档:
{
_id: 5,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 6 },
{ grade: 90, mean: 85, std: 3 }
]
}