$ (update)
On this page本页内容
Definition定义
$
-
The positional位置运算符$
operator identifies an element in an array to update without explicitly specifying the position of the element in the array.$
标识数组中要更新的元素,而不显式指定该元素在数组中的位置。NoteDisambiguation消除歧义To project, or return, an array element from a read operation, see the若要从读取操作投影或返回数组元素,请参阅$
projection operator instead.$
投影运算符。To update all elements in an array, see the all positional operator若要更新数组中的所有元素,请改为查看所有位置运算符$[]
instead.$[]
。To update all elements that match an array filter condition or conditions, see the filtered positional operator instead要更新与数组筛选条件匹配的所有元素,请参阅已筛选的位置运算符$[<identifier>]
.$[<identifier>]
。
The positional位置$
operator has the form:$
运算符的形式为:{ "<array>.$" : value }
When used with update operations, e.g.当与更新操作一起使用时,例如db.collection.updateOne()
anddb.collection.findAndModify()
,db.collection.updateOne()
和db.collection.findAndModify()
,the positional位置$
operator acts as a placeholder for the first element that matches thequery document
, and$
运算符充当与查询文档匹配的第一个元素的占位符,并且thearray
field must appear as part of thequery document
.array
字段必须作为query
文档的一部分出现。
For example:例如:db.collection.updateOne(
{ <array>: value ... },
{ <update operator>: { "<array>.$" : value } }
)
Behavior行为
Starting in MongoDB 5.0, update operators process document fields with string-based names in lexicographic order. 从MongoDB 5.0开始,update运算符按照字典顺序处理具有基于字符串的名称的文档字段。Fields with numeric names are processed in numeric order. 具有数字名称的字段按数字顺序处理。See Update Operators Behavior for details.有关详细信息,请参阅更新运算符行为。
upsert
Do not use the positional operator 不要在$
with upsert operations because inserts will use the $
as a field name in the inserted document.upsert
操作中使用位置运算符$
,因为插入操作将使用$
作为插入文档中的字段名。
Nested Arrays嵌套数组
The positional 位置$
operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $
placeholder is a single value$
运算符不能用于遍历多个数组的查询,例如遍历嵌套在其他数组中的数组的查询。因为$
占位符的替换为单个值
Unsets
When used with the 与$unset
operator, the positional $
operator does not remove the matching element from the array but rather sets it to null
.$unset
运算符一起使用时,位置$
运算符不会从数组中删除匹配元素,而是将其设置为null
。
Negations否定
If the query matches the array using a negation operator, such as 如果查询使用否定运算符(如$ne
, $not
, or $nin
, then you cannot use the positional operator to update values from this array.$ne
、$not
或$nin
)与数组匹配,则不能使用位置运算符更新此数组中的值。
However, if the negated portion of the query is inside of an 但是,如果查询的否定部分在$elemMatch
expression, then you can use the positional operator to update this field.$elemMatch
表达式内部,则可以使用位置运算符来更新此字段。
Multiple Array Matches多个数组匹配
The positional 在对多个数组字段进行筛选时,位置$
update operator behaves ambiguously when filtering on multiple array fields.$
更新运算符的行为不明确。
When the server executes an update method, it first runs a query to determine which documents you want to update. 当服务器执行更新方法时,它首先运行一个查询来确定要更新哪些文档。If the update filters documents on multiple array fields, the subsequent call to the positional 如果更新筛选了多个数组字段上的文档,那么对位置$
update operator doesn't always update the required position in the array.$
更新运算符的后续调用并不总是更新数组中所需的位置。
Examples实例
Update Values in an Array更新数组中的值
Create a collection 使用以下文档创建students
with the following documents:students
集合:
db.students.insertMany( [
{ "_id" : 1, "grades" : [ 85, 80, 80 ] },
{ "_id" : 2, "grades" : [ 88, 90, 92 ] },
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }
] )
To update the first element whose value is 要将80
to 82
in the in the grades
array, use the positional $
operator if you do not know the position of the element in the array:grades
数组中值为80
第一个元素更新为82
,如果您不知道该元素在数组中的位置,请使用位置$
运算符:
You must include the array field as part of the 必须将数组字段作为query
document.query
文档的一部分。
db.students.updateOne(
{ _id: 1, grades: 80 },
{ $set: { "grades.$" : 82 } }
)
The positional 位置$
operator acts as a placeholder for the first match of the update query document.$
运算符充当更新query
文档的第一个匹配项的占位符。
After the operation, the 操作后,students
collection contains the following documents:students
集合包含以下文档:
{ "_id" : 1, "grades" : [ 85, 82, 80 ] }
{ "_id" : 2, "grades" : [ 88, 90, 92 ] }
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }
Update Documents in an Array更新数组中的文档
The positional 位置$
operator facilitates updates to arrays that contain embedded documents. $
运算符便于更新包含嵌入文档的数组。Use the positional 使用位置$
operator to access the fields in the embedded documents with the dot notation on the $
operator.$
运算符访问嵌入文档中的字段,并在$
运算符上使用点符号。
db.collection.updateOne(
{ <query selector> },
{ <update operator>: { "array.$.field" : value } }
)
Consider the following document in the 考虑students
collection whose grades
element value is an array of embedded documents:students
集合中的以下文档,其grades
元素值是嵌入文档的数组:
{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 85, mean: 85, std: 8 }
]
}
Use the positional 使用位置$
operator to update the std
field of the first array element that matches the grade
equal to 85
condition:$
运算符更新第一个数组元素的std
字段,该字段与grade
等于85的条件相匹配:
You must include the array field as part of the 必须将数组字段作为query
document.query
文档的一部分。
db.students.updateOne(
{ _id: 4, "grades.grade": 85 },
{ $set: { "grades.$.std" : 6 } }
)
After the operation, the document has the following updated values:操作后,文档具有以下更新值:
{
"_id" : 4,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 8 },
{ "grade" : 85, "mean" : 90, "std" : 6 },
{ "grade" : 85, "mean" : 85, "std" : 8 }
]
}
Update Embedded Documents Using Multiple Field Matches使用多个字段匹配更新嵌入文档
The $
operator can update the first array element that matches multiple query criteria specified with the $elemMatch
operator.$
运算符可以更新与$elemMatch
运算符指定的多个查询条件匹配的第一个数组元素。
Consider the following document in the 考虑students
collection whose grades
field value is an array of embedded documents:students
集合中的以下文档,其grades
字段值是嵌入文档的数组:
{
_id: 5,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 90, mean: 85, std: 3 }
]
}
In the example below, the 在下面的示例中,$
operator updates the value of the std
field in the first embedded document that has grade
field with a value less than or equal to 90
and a mean
field with a value greater than 80
:$
运算符更新第一个嵌入文档中std
字段的值,该文档的grades
字段的值小于或等于90
,mean
字段的值大于80
:
db.students.updateOne(
{
_id: 5,
grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } }
},
{ $set: { "grades.$.std" : 6 } }
)
This operation updates the first embedded document that matches the criteria, namely the second embedded document in the array:此操作更新与条件匹配的第一个嵌入文档,即数组中的第二个嵌入文档:
{
_id: 5,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 6 },
{ grade: 90, mean: 85, std: 3 }
]
}
Update with Multiple Array Matches使用多个数组匹配进行更新
The positional 当查询具有多个数组字段以筛选集合中的文档时,位置$
update operator behaves ambiguously when the query has multiple array fields to filter documents in the collection.$
更新运算符的行为不明确。
Consider a document in the 考虑students_deans_list
collection, which holds arrays of student information:students_deans_list
集合中的一个文档,该文档包含学生信息的数组:
db.students_deans_list.insertMany( [
{
_id: 8,
activity_ids: [ 1, 2 ],
grades: [ 90, 95 ],
deans_list: [ 2021, 2020 ]
}
] )
In the following example, the user attempts to modify the 在以下示例中,用户尝试修改deans_list
field, filtering documents using the activity_ids
, deans_list
, and grades
fields, and updating the 2021 value in the deans_list
field to 2022:deans_list
字段,使用activity_ids
、deans_list
和grades
字段筛选文档,并将deans_list
字段中的值2021
更新为2022
:
db.students_deans_list.updateOne(
{ activity_ids: 1, grades: 95, deans_list: 2021 },
{ $set: { "deans_list.$": 2022 } }
)
When the server executes the 当服务器执行上面的updateOne
method above, it filters the available documents using values in the supplied array fields. updateOne
方法时,它会使用提供的数组字段中的值来筛选可用文档。Although the 尽管deans_list
field is used in the filter, it is not the field used by the positional $
update operator to determine which position in the array to update:deans_list
字段在筛选器中使用,但它不是位置$
更新运算符用来确定要更新数组中哪个位置的字段:
db.students_deans_list.find( { _id: 8 } )
Example output:示例输出:
{
_id: 8,
activity_ids: [ 1, 2 ],
grades: [ 90, 95 ],
deans_list: [ 2021, 2022 ]
}
The updateOne
method matched the deans_list
field on 2021, but the positional $
update operator instead changed the 2020 value to 2022.updateOne
方法与deans_list
字段在2021
上匹配,但位置$
更新运算符将2020
值改为2022
。
To avoid unexpected results when matching on multiple arrays, instead use the filtered positional operator 为了避免在多个数组上匹配时出现意外结果,请改用筛选后的位置运算符$[<identifier>]
.$[<identifier>]
。