Docs HomeNode.js

Update Arrays in a Document更新文档中的数组

Overview概述

In this guide, you can learn how to use the following array update operators to modify an array embedded within a document:在本指南中,您可以学习如何使用以下数组更新运算符来修改嵌入在文档中的数组:

For a list of array update operators, see Update Operators in the Server Manual documentation.有关数组更新运算符的列表,请参阅服务器手册文档中的更新运算符

Specifying Array Elements指定数组元素

Positional operators specify which array elements to update. 位置运算符指定要更新的数组元素。You can use these operators to apply updates to the first element, all elements, or certain elements of an array that match a criteria.可以使用这些运算符将更新应用于数组中与条件匹配的第一个元素、所有元素或某些元素。

To specify elements in an array with positional operators, use dot notation. 要使用位置运算符指定数组中的元素,请使用点表示法Dot notation is a property access syntax for navigating BSON objects. 点表示法是一种用于导航BSON对象的属性访问语法。To learn more, see dot notation.要了解更多信息,请参阅点表示法

The First Matching Array Element第一个匹配数组元素

To update the first array element of each document that matches your query, use the positional operator $.要更新与查询匹配的每个文档的第一个数组元素,请使用位置运算符$

The positional operator $ references the array matched by the query. 位置运算符$引用查询匹配的数组。You cannot use this operator to reference a nested array. 不能使用此运算符引用嵌套数组。If you want to access a nested array, use the filtered positional operator.如果要访问嵌套数组,请使用筛选后的位置运算符

Important

Do not use the $ operator in an upsert call because the driver treats $ as a field name in the insert document.不要在upsert调用中使用$运算符,因为驱动程序将$视为插入文档中的字段名。

Example实例

This example uses the following sample document to show how to update the first matching array element:此示例使用以下示例文档来显示如何更新第一个匹配的数组元素:

{
_id: ...,
entries: [
{ x: false, y: 1 },
{ x: "hello", y: 100 },
{ x: "goodbye", y: 1000 }
]
}

The following code shows how to increment a value in the first array element that matches a query.以下代码显示如何在与查询匹配的第一个数组元素中增加值。

The query matches elements in the entries array where the value of x is a string type. 查询匹配entries数组中的元素,其中x的值是string类型。The update increases the y value by 33 in the first matching element.更新将第一匹配元素中的y值增加33

const query = { "entries.x": { $type : "string" } };
const updateDocument = {
$inc: { "entries.$.y": 33 }
};
const result = await myColl.updateOne(query, updateDocument);

After you run the update operation, the document resembles the following:运行更新操作后,文档类似于以下内容:

{
_id: ...,
entries: [
{ x: false, y: 1 },
{ x: "hello", y: 133 },
{ x: "goodbye", y: 1000 }
]
}

The example includes the entries.x field in the query to match the array that the $ operator applies an update to. 该示例包括查询中的entries.x字段,以匹配$运算符应用更新的数组。If you omit the entries.x field from the query while using the $ operator in an update, the driver is unable to identify the matching array and raises the following error:如果在更新中使用$运算符时从查询中省略entries.x字段,则驱动程序将无法识别匹配的数组,并引发以下错误:

MongoServerError: The positional operator did not find the match needed from the query.

Matching All Array Elements匹配所有数组元素

To perform the update on all of the array elements of each document that matches your query, use the all positional operator $[].要对与查询匹配的每个文档的所有数组元素执行更新,请使用所有位置运算符$[]

Example实例

This example uses the following sample documents, which describe phone call logs, to show how to update all matching array elements:本示例使用以下描述电话呼叫日志的示例文档来显示如何更新所有匹配的数组元素:

{
_id: ...,
date: "5/15/2023",
calls: [
{ time: "10:08 am", caller: "Mom", duration: 67 },
{ time: "4:11 pm", caller: "Dad", duration: 121 },
{ time: "6:36 pm", caller: "Grandpa", duration: 13 }
]
},
{
_id: ...,
date: "5/16/2023",
calls: [
{ time: "11:47 am", caller: "Mom", duration: 4 },
]
}

The following code shows how to remove the duration field from all calls array entries in the document whose date is "5/15/2023":以下代码显示如何从date"5/15/2023"的文档中的所有calls数组条目中删除duration字段:

const query = { date: "5/15/2023" };
const updateDocument = {
$unset: { "calls.$[].duration": "" }
};
const result = await myColl.updateOne(query, updateDocument);

After you run the update operation, the documents resemble the following:运行更新操作后,文档如下所示:

{
_id: ...,
date: "5/15/2023",
calls: [
{ time: "10:08 am", caller: "Mom" },
{ time: "4:11 pm", caller: "Dad" },
{ time: "6:36 pm", caller: "Grandpa" }
]
},
{
_id: ...,
date: "5/16/2023",
calls: [
{ time: "11:47 am", caller: "Mom", duration: 4 },
]
}

Matching Multiple Array Elements匹配多个数组元素

To perform an update on all embedded array elements of each document that matches your query, use the filtered positional operator $[<identifier>].要对与查询匹配的每个文档的所有嵌入数组元素执行更新,请使用筛选后的位置运算符$[<identifier>]

The filtered positional operator $[<identifier>] specifies the matching array elements in the update document. 筛选后的位置运算符$[<identifier>]指定更新文档中匹配的数组元素。To identify which array elements to match, pair this operator with <identifier> in an arrayFilters object.要确定要匹配的数组元素,请将此运算符与arrayFilters对象中的<identifier>配对。

The <identifier> placeholder represents an element of the array field. <identifier>占位符表示数组字段的一个元素。You must select a value for <identifier> that starts with a lowercase letter and contains only alphanumeric characters.您必须为<identifier>选择一个以小写字母开头且仅包含字母数字字符的值。

Usage用法

You can use a filtered positional operator in an update operation. 可以在更新操作中使用筛选后的位置运算符。An update operation takes a query, an update document, and optionally, an options object as its parameters.更新操作将查询、更新文档以及可选的选项对象作为其参数。

The following steps describe how to use a filtered positional operator in an update operation:以下步骤描述了如何在更新操作中使用筛选后的位置运算符:

  1. Format your update document as follows:按以下方式设置更新文档的格式:

    { $<operator>: { "<array>.$[<identifier>].<arrayField>": <updateParameter> } }

    This update document contains the following placeholders:此更新文档包含以下占位符:

    • $<operator>: The array update operator:数组更新运算符
    • <array>: The array in the document to update:文档中要更新的数组
    • <identifier>: The identifier for the filtered positional operator:已筛选的位置运算符的标识符
    • <arrayField>: The field in the <array> array element to update:要更新的<array>数组元素中的字段
    • <updateParameter>: The value that describes the update:描述更新的值
  2. Add the matching criteria in the arrayFilters object. arrayFilters对象中添加匹配条件。This object is an array of queries that specify which array elements to include in the update. 此对象是一个查询数组,用于指定要包含在更新中的数组元素。Set this object in an options parameter:options参数中设置此对象:

    arrayFilters: [
    { "<identifier>.<arrayField1>": <updateParameter1> },
    { "<identifier>.<arrayField2>": <updateParameter2> },
    ...
    ]
  3. Pass the query, the update document, and options to an update method. 将查询、更新文档和选项传递给更新方法。The following sample code shows how to call the updateOne() method with these parameters:以下示例代码显示了如何使用这些参数调用updateOne()方法:

    await myColl.updateOne(query, updateDocument, options);

Example实例

This example uses the following sample documents, which describe shopping lists for specific recipes, to show how to update certain matching array elements:本示例使用以下示例文档来说明如何更新某些匹配的数组元素,这些文档描述了特定食谱的购物列表:

{
_id: ...,
date: "11/12/2023",
items: [
{ item: "Scallions", quantity: 3, recipe: "Fried rice" },
{ item: "Mangos", quantity: 4, recipe: "Salsa" },
{ item: "Pork shoulder", quantity: 1, recipe: "Fried rice" },
{ item: "Sesame oil", quantity: 1, recipe: "Fried rice" }
]
},
{
_id: ...,
date: "11/20/2023",
items: [
{ item: "Coffee beans", quantity: 1, recipe: "Coffee" }
]
}

Suppose you want to increase the quantity of items you purchase for a recipe on your "11/12/2023" grocery trip. 假设你想在"11/12/2023"的杂货之旅中增加你为食谱购买的商品数量。You want to double the quantity if the item meets all the following criteria:如果项目满足以下所有条件,则需要将数量增加一倍:

  • The item is for the "Fried rice" recipe.这是"Fried rice"的菜谱。
  • The item name does not include the word "oil".项目名称中不包含"oil"一词。

To double the quantity value in the matching array entries, use the filtered positional operator as shown in the following code:要将匹配数组项中的quantity值加倍,请使用筛选后的位置运算符,如以下代码所示:

const query = { date: "11/12/2023" };
const updateDocument = {
$mul: { "items.$[i].quantity": 2 }
};
const options = {
arrayFilters: [
{
"i.recipe": "Fried rice",
"i.item": { $not: { $regex: "oil" } },
}
]
};
const result = await myColl.updateOne(query, updateDocument, options);

The update multiplied the quantity value by 2 for items that matched the criteria. 对于符合条件的物料,更新将quantity值乘以2The item "Sesame oil" did not match the criteria in the arrayFilters object and therefore was excluded from the update. 项目"Sesame oil"arrayFilters对象中的条件不匹配,因此被排除在更新之外。The following documents reflect these changes:以下文件反映了这些变化:

{
_id: ...,
date: "11/12/2023",
items: [
{ item: "Scallions", quantity: 6, recipe: "Fried rice" },
{ item: "Mangos", quantity: 4, recipe: "Salsa" },
{ item: "Pork shoulder", quantity: 2, recipe: "Fried rice" },
{ item: "Sesame oil", quantity: 1, recipe: "Fried rice" }
]
},
{
_id: ...,
date: "11/20/2023",
items: [
{ item: "Coffee beans", quantity: 1, recipe: "Coffee" }
]
}