$ (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.定位$运算符标识数组中要更新的元素,而不显式指定元素在数组中的位置。

Disambiguation消歧

  • 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.update() and db.collection.findAndModify(),与更新操作一起使用时,例如db.collection.update()db.collection.findAndModify()

  • the positional $ operator acts as a placeholder for the first element that matches the query document, and定位$运算符充当与查询文档匹配的第一个元素的占位符,并且
  • the array field must appear as part of the query document.array字段必须作为查询文档的一部分出现。

For example:例如:

db.collection.update(
   { <array>: value ... },
   { <update operator>: { "<array>.$" : value } }
)

Behavior行为

upsert

Do not use the positional operator $ with upsert operations because inserts will use the $ as a field name in the inserted document.不要将位置运算符$用于upsert操作,因为inserts将使用$作为插入文档中的字段名。

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表达式内,则可以使用位置运算符更新此字段。

Examples示例

Update Values in an Array更新数组中的值

Create a collection students with the following documents:使用以下文档创建一个集合students

db.students.insert([
   { "_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数组中值为8082的第一个元素,如果不知道该元素在数组中的位置,请使用定位$运算符:

Important

You must include the array field as part of the query document.必须将数组字段作为查询文档的一部分包含在内。

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.定位$运算符充当更新查询文档的第一个匹配项的占位符。

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.update(
   { <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:使用定位$运算符更新与grade等于85条件匹配的第一个数组元素的std字段:

Important重要的

You must include the array field as part of the query document.必须将数组字段作为查询文档的一部分包含在内。

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字段的值,该文档的grade字段的值小于或等于90mean字段的值大于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 }
  ]
}