$[<identifier>]

On this page本页内容

Definition定义

$[<identifier>]

New in version 3.6.版本3.6中的新功能。

The filtered positional operator $[<identifier>] identifies the array elements that match the arrayFilters conditions for an update operation, e.g. db.collection.update() and db.collection.findAndModify().筛选位置运算符$[<identifier>]标识与arrayFilters条件相匹配的数组元素用于更新操作,例如db.collection.update()db.collection.findAndModify()

Used in conjunction with the arrayFilters option, the $[<identifier>] operator has the following form:arrayFilters选项一起使用,$[<identifier>]运算符的形式如下:

{ <update operator>: { "<array>.$[<identifier>]" : value } },
{ arrayFilters: [ { <identifier>: <condition> } ] }

Use in conjunction with the arrayFilters option to update all elements that match the arrayFilters conditions in the document or documents that match the query conditions. arrayFilters选项结合使用,以更新文档中与arrayFilters条件匹配的所有元素或与查询条件匹配的文档。For example:例如:

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

Note

The <identifier> must begin with a lowercase letter and contain only alphanumeric characters.<identifier>必须以小写字母开头,并且只包含字母数字字符。

For an example, see Update All Array Elements That Match arrayFilters.有关示例,请参阅更新与ArrayFilter匹配的所有数组元素

Behavior行为

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 $[<identifier>] in the update statement.如果upsert操作导致插入,则query必须在数组字段中包含完全相等的匹配项,以便在更新语句中使用$[<identifier>]

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

db.collection.update(
   { myArray: [ 0, 1 ] },
   { $set: { "myArray.$[element]": 2 } },
   { arrayFilters: [ { element: 0 } ],
     upsert: true }
)

If no such document exists, the operation would result in an insert of a document that resembles the following:如果不存在此类文件,操作将导致插入类似以下内容的文件:

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

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.array.update(
   { },
   { $set: { "myArray.$[element]": 10 } },
   { arrayFilters: [ { element: 9 } ],
     upsert: true }
)

The operation would return an error that resembles the following:该操作将返回一个类似于以下内容的错误:

WriteResult({
   "nMatched" : 0,
   "nUpserted" : 0,
   "nModified" : 0,
   "writeError" : {
      "code" : 2,
      "errmsg" : "The path 'myArray' must exist in the document in order to apply array updates."
   }
})

Nested Arrays嵌套数组

The filtered positional operator $[<identifier>] can be used for queries which traverse more than one array and nested arrays.筛选后的位置运算符$[<identifier>]可用于遍历多个数组和嵌套数组的查询。

For an example, see Update Nested Arrays in Conjunction with $[].有关示例,请参阅结合$[]更新嵌套数组

Examples示例

Update All Array Elements That Match arrayFilters更新与arrayFilters匹配的所有数组元素

Consider a collection students with the following documents:考虑一个集合students带有下列文档:

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

To update all elements that are greater than or equal to 100 in the grades array, use the filtered positional operator $[<identifier>] with the arrayFilters:要更新grades数组中大于或等于100的所有元素,请将筛选后的位置运算符$[<identifier>]arrayFilters一起使用:

db.students.update(
   { },
   { $set: { "grades.$[element]" : 100 } },
   { multi: true,
     arrayFilters: [ { "element": { $gte: 100 } } ]
   }
)

The positional $[<identifier>] operator acts as a placeholder for all elements in the array field that match the conditions specified in arrayFilters位置$[<identifier>]运算符充当数组字段中与arrayFilters中指定的条件匹配的所有元素的占位符.

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

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

Update All Documents That Match arrayFilters in an Array更新与数组中的arrayFilters匹配的所有文档

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

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

Consider a collection students2 with the following documents:考虑一个集合students2具有以下文档:

{
   "_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 }
   ]
}

To modify the value of the mean field for all elements in the grades array where the grade is greater than or equal to 85, use the positional $[<identifier>] operator and arrayFilters:要修改grade大于或等于85grades数组中所有元素的mean字段,请使用位置运算符$[<identifier>]arrayFilters

db.students2.update(
   { },
   { $set: { "grades.$[elem].mean" : 100 } },
   {
     multi: true,
     arrayFilters: [ { "elem.grade": { $gte: 85 } } ]
   }
)

After the operation, the collection has the following documents:操作完成后,集合具有以下文档:

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

Update All Array Elements that Match Multiple Conditions更新所有匹配多个条件的数组元素

Consider a collection students2 with the following documents:考虑一个集合students2带有以下文档:

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

To modify the value of the std field for all elements in the grades array where both the grade is greater than or equal to 80 and the std is greater than or equal to 5, use the positional $[<identifier>] operator and arrayFilters:要修改grades数组中grades大于或等于80std大于或等于5的所有元素的std字段值,请使用位置运算符$[<identifier>]arrayFilters

db.students2.update(
   { },
   { $inc: { "grades.$[elem].std" : -1 } },
   { arrayFilters: [ { "elem.grade": { $gte: 80 }, "elem.std": { $gt: 5 } } ], multi: true }
)

After the operation, the collection has the following documents:操作完成后,集合具有以下文档:

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

Update Array Elements Using a Negation Operator使用求反运算符更新数组元素

Consider a collection alumni with the following documents:考虑一个集合alumni带有以下文档:

{
   "_id": 1,
   "name": "Christine Franklin",
   "degrees": [
      { "level": "Master",
        "major": "Biology",
        "completion_year": 2010,
        "faculty": "Science"
      },
      {
        "level": "Bachelor",
        "major": "Biology",
        "completion_year": 2008,
        "faculty": "Science"
      }
   ],
   "school_email": "cfranklin@example.edu",
   "email": "christine@example.com"
}
{
   "_id": 2,
   "name": "Reyansh Sengupta",
   "degrees": [
      { "level": "Bachelor",
        "major": "Chemical Engineering",
        "completion_year": 2002,
        "faculty": "Engineering"
      }
   ],
   "school_email": "rsengupta2@example.edu"
}

To modify all elements in the degrees array that do not have "level": "Bachelor", use the positional [<identifier>] operation with the $ne query operator:要修改degrees数组中没有"level": "Bachelor"的所有元素,请使用位置[<identifier>]操作和$ne查询运算符:

db.alumni.update(
   { },
   { $set : { "degrees.$[degree].gradcampaign" : 1 } },
   { arrayFilters : [ {"degree.level" : { $ne: "Bachelor" } } ],
     multi : true }
)

After the operation, the collection has the following documents:操作完成后,集合具有以下文档:

{
   "_id" : 1,
   "name" : "Christine Franklin",
   "degrees" : [
      {
         "level" : "Master",
         "major" : "Biology",
         "completion_year" : 2010,
         "faculty" : "Science",
         "gradcampaign" : 1
      },
      {
         "level" : "Bachelor",
         "major" : "Biology",
         "completion_year" : 2008,
         "faculty" : "Science"
      }
   ],
   "school_email" : "cfranklin@example.edu",
   "email" : "christine@example.com"
}
{
   "_id" : 2,
   "name" : "Reyansh Sengupta",
   "degrees" : [
      {
         "level" : "Bachelor",
         "major" : "Chemical Engineering",
         "completion_year" : 2002,
         "faculty" : "Engineering"
      }
   ],
   "school_email" : "rsengupta2@example.edu"
}

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

The $[<identifier>] filtered positional operator, in conjunction with the $[] all positional operator, can be used to update nested arrays.$[<identifier>]筛选的位置运算符与$[]全部位置运算符一起可用于更新嵌套数组。

Create a collection students3 with the following document:创建一个集合students3带有以下文档:

db.students3.insert(
   { "_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 ] },

      ]
   }
)

The following updates the values that are greater than or equal to 8 in the nested grades.questions array if the associated grades.type field is quiz.以下内容将更新嵌套grades.questions数组中大于或等于8的值,如果相关联的grades.type字段是quiz

db.students3.update(
   {},
   { $inc: { "grades.$[t].questions.$[score]": 2 } },
   { arrayFilters: [ { "t.type": "quiz" } , { "score": { $gte: 8 } } ], multi: true}
)

After the operation, the collection has the following document:操作完成后,集合具有以下文档:

{
   "_id" : 1,
   "grades" : [
      { "type" : "quiz", "questions" : [ 12, 10, 5 ] },
      { "type" : "quiz", "questions" : [ 10, 11, 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.update(
   {},
   { $inc: { "grades.$[].questions.$[score]": 2 } },
   { arrayFilters: [  { "score": { $gte: 8 } } ], multi: true}
)