Database Manual / Reference / Query Language / Update / Arrays

$[] (positional array-wide update operator)(位置数组范围更新运算符)

Definition定义

$[]

The all positional operator $[] indicates that the update operator should modify all elements in the specified array field.全位置运算符$[]表示更新运算符应修改指定数组字段中的所有元素。

The $[] operator has the following form:$[]运算符具有以下形式:

{ <update operator>: { "<array>.$[]" : value } }

Use in update operations, e.g. db.collection.updateOne() and db.collection.findAndModify(), to modify all array elements for the document or documents that match the query condition. For example:在更新操作中使用,例如db.collection.updateOne()db.collection.findAndModify(),以修改与查询条件匹配的文档的所有数组元素。例如:

db.collection.updateOne(
{ <query conditions> },
{ <update operator>: { "<array>.$[]" : value } }
)

For an example, see Update All Elements in an Array.例如,请参阅更新数组中的所有元素

Behavior行为

Starting in MongoDB 5.0, update operators process document fields with string-based names in lexicographic order. Fields with numeric names are processed in numeric order. See Update Operators Behavior for details.从MongoDB 5.0开始,更新运算符按字典顺序处理具有基于字符串的名称的文档字段。具有数字名称的字段按数字顺序处理。有关详细信息,请参阅更新运算符行为

upsert

If an upsert operation results in an insert, the query must include an exact equality match on the array field in order to use the $[] positional operator in the update statement.如果upsert导致插入,则query必须在数组字段上包含完全相等的匹配,以便在更新语句中使用$[]位置运算符。

For example, the following upsert operation, which uses $[] in the update document, specifies an exact equality match condition on the array field:例如,以下在更新文档中使用$[]的upsert操作在数组字段上指定了一个完全相等的匹配条件:

db.collection.updateOne(
{ myArray: [ 5, 8 ] },
{ $set: { "myArray.$[]": 10 } },
{ upsert: true }
)

If no such document exists, the operation would result in an insertion of the following document:如果不存在此类文档,则操作将导致插入以下文档:

{ "_id" : ObjectId(...), "myArray" : [ 10, 10 ] }

If the upsert operation did not include an exact equality match and no matching documents were found to update, the upsert operation would error.如果upsert操作不包括完全相等的匹配,并且找不到要更新的匹配文档,则upsert操作将出错。

For example, the following operations would error if no matching documents were found to update:例如,如果找不到要更新的匹配文档,则以下操作将出错:

db.emptyCollection.updateOne(
{ },
{ $set: { "myArray.$[]": 10 } },
{ upsert: true }
)

db.emptyCollection.updateOne(
{ myArray: 5 },
{ $set: { "myArray.$[]": 10 } },
{ upsert: true }
)

Nested Arrays嵌套数组

The $[] operator can be used for queries that traverse more than one array and nested arrays.$[]运算符可用于遍历多个数组和嵌套数组的查询。

For an example, see Update Nested Arrays in Conjunction with $[<identifier>].例如,请参阅$[<identifier>]结合更新嵌套数组

Examples示例

Update All Elements in an Array更新数组中的所有元素

Create the students collection:创建students集合:

db.students.insertMany( [
{ "_id" : 1, "grades" : [ 85, 82, 80 ] },
{ "_id" : 2, "grades" : [ 88, 90, 92 ] },
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }
] )

To increment all elements in the grades array by 10 for all documents in the collection, use the all positional $[] operator:要将集合中所有文档的grades数组中的所有元素递增10,请使用全位置$[]运算符:

db.students.updateMany(
{ },
{ $inc: { "grades.$[]": 10 } },
)

The all positional $[] operator acts as a placeholder for all elements in the array field.全位置$[]运算符充当数组字段中所有元素的占位符。

After the operation, the students collection contains the following documents:操作后,students集合包含以下文件:

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 102 ] }
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }

Update All Documents in an Array更新数组中的所有文档

The $[] positional operator facilitates updates to arrays that contain embedded documents. $[]位置运算符便于更新包含嵌入式文档的数组。To access the fields in the embedded documents, use the dot notation with the $[] operator.要访问嵌入文档中的字段,请使用带有$[]运算符的点符号

db.collection.updateOne(
{ <query selector> },
{ <update operator>: { "array.$[].field" : value } }
)

Create the students2 collection:创建students2集合:

db.students2.insertMany( [
{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 8 },
{ "grade" : 85, "mean" : 90, "std" : 6 },
{ "grade" : 85, "mean" : 85, "std" : 8 }
]
},
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 8 },
{ "grade" : 87, "mean" : 90, "std" : 5 },
{ "grade" : 85, "mean" : 85, "std" : 6 }
]
}
] )

To modify the value of the std field for all elements in the grades array, use the positional $[] operator:要修改grades数组中所有元素的std字段的值,请使用位置$[]运算符:

db.students2.updateMany(
{ },
{ $inc: { "grades.$[].std" : -2 } },
)

After the operation, the collection has the following documents:操作后,集合有以下文件:

{
"_id" : 1,
"grades" : [
{ "grade" : 80, "mean" : 75, "std" : 6 },
{ "grade" : 85, "mean" : 90, "std" : 4 },
{ "grade" : 85, "mean" : 85, "std" : 6 }
]
}
{
"_id" : 2,
"grades" : [
{ "grade" : 90, "mean" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}

Update Arrays Specified Using a Negation Query Operator更新使用否定查询运算符指定的数组

Create the results collection:创建results集合:

db.results.insertMany( [
{ "_id" : 1, "grades" : [ 85, 82, 80 ] },
{ "_id" : 2, "grades" : [ 88, 90, 92 ] },
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }
] )

To increment all elements in the grades array by 10 for all documents except those with the value 100 in the grades array, use the all positional $[] operator:要为除grades数组中值为100的文档之外的所有文档将成绩数组中的所有元素递增10,请使用全位置$[]运算符:

db.results.updateMany(
{ "grades" : { $ne: 100 } },
{ $inc: { "grades.$[]": 10 } },
)

The all positional $[] operator acts as a placeholder for all elements in the array field.全位置$[]运算符充当数组字段中所有元素的占位符。

After the operation, the students collection contains the following documents:操作后,students集合包含以下文件:

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 102 ] }
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }

Update Nested Arrays in Conjunction with $[<identifier>]$[<identifier>]结合更新嵌套数组

The $[] positional operator, in conjunction with filter $[<identifier>] positional operator can be used to update nested arrays.$[]位置运算符与筛选器$[<identifier>]位置运算符可用于更新嵌套数组。

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

db.students3.insertMany( [
{ "_id" : 1,
"grades" : [
{ type: "quiz", questions: [ 10, 8, 5 ] },
{ type: "quiz", questions: [ 8, 9, 6 ] },
{ type: "hw", questions: [ 5, 4, 3 ] },
{ type: "exam", questions: [ 25, 10, 23, 0 ] },
]
}
] )

To update all values that are greater than or equal to 8 in the nested grades.questions array, regardless of type:要更新嵌套grades.questions数组中大于或等于8的所有值,无论其type如何:

db.students3.updateMany(
{},
{ $inc: { "grades.$[].questions.$[score]": 2 } },
{ arrayFilters: [ { "score": { $gte: 8 } } ] }
)

The updated documents look like this:更新后的文档如下:

{
_id: 1,
grades: [
{ type: 'quiz', questions: [ 12, 10, 5 ] },
{ type: 'quiz', questions: [ 10, 11, 6 ] },
{ type: 'hw', questions: [ 5, 4, 3 ] },
{ type: 'exam', questions: [ 27, 12, 25, 0 ] }
]
}

Learn More了解更多

For examples that use the $[] operator to update arrays, see Update Array Elements in a Document with MQL Positional Operators.有关使用$[]运算符更新数组的示例,请参阅使用MQL位置运算符更新文档中的数组元素