Menu Docs
Página inicial do Docs
/ / /
Node.js
/ / /

Atualizar Matrizes em um Documento

Nesta página

  • Visão geral
  • Especificando Elementos de Array
  • O Primeiro Elemento de Array Correspondente
  • Correspondendo todos os elementos da array
  • Combinando vários elementos da matriz

Neste guia, você pode aprender a usar os seguintes operadores de atualização de array para modificar uma array incorporada em um documento:

  • Operador posicional: $

  • Todos os operadores posicionais: $[]

  • Operador posicional filtrado: $[<identifier>]

Para obter uma lista de operadores de atualização de array, consulte Operadores de atualização na documentação do Manual do Servidor.

Os operadores posicionais especificam quais elementos da array devem ser atualizados. Você pode usar esses operadores para aplicar atualizações ao primeiro elemento, a todos os elementos ou a determinados elementos de uma array que correspondam a um critério.

Para especificar elementos em uma array com operadores posicionais, use a notação de ponto. A notação de ponto é uma sintaxe de acesso à propriedade para navegar em objetos BSON. Para saber mais, consulte notação de ponto.

Para atualizar o primeiro elemento de array de cada documento que corresponda à sua query, use o operador posicional $.

O operador posicional $ faz referência à array correspondente à consulta. Você não pode usar esse operador para fazer referência a uma array aninhada. Se quiser acessar uma array aninhada, use o operador posicional filtrado.

Importante

Não utilize o operador $ numa chamada upsert porque o condutor trata $ como um nome de campo no documento de inserção.

Este exemplo usa o seguinte documento de amostra para mostrar como atualizar o primeiro elemento de array correspondente:

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

O código a seguir mostra como incrementar um valor no primeiro elemento de array que corresponde a uma consulta.

A query corresponde aos elementos da array entries em que o valor de x é do tipo string . A atualização aumenta o valor y em 33 no primeiro elemento correspondente.

// Query for all elements in entries array where the value of x is a string
const query = { "entries.x": { $type : "string" } };
// On first matched element, increase value of y by 33
const updateDocument = {
$inc: { "entries.$.y": 33 }
};
// Execute the update operation
const result = await myColl.updateOne(query, updateDocument);

Depois de executar a operação de atualização, o documento será semelhante ao seguinte:

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

O exemplo inclui o campo entries.x na query para corresponder à array à qual o operador $ aplica uma atualização. Se você omitir o campo entries.x da query ao usar o operador $ em uma atualização, o driver não consegue identificar a array correspondente e gera o seguinte erro:

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

Para executar a atualização em todos os elementos de array de cada documento que corresponda à sua consulta, use o operador posicional all $[].

Este exemplo usa os seguintes documentos de exemplo, que descrevem registros de chamadas telefônicas, para mostrar como atualizar todos os elementos correspondentes da array:

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

O código a seguir mostra como remover o campo duration de todas as entradas de array calls no documento cuja date é "5/15/2023":

// Query for all documents where date is the string "5/15/2023"
const query = { date: "5/15/2023" };
// For each matched document, remove duration field from all entries in calls array
const updateDocument = {
$unset: { "calls.$[].duration": "" }
};
// Execute the update operation
const result = await myColl.updateOne(query, updateDocument);

Após executar a operação de atualização, os documentos se assemelham ao seguinte:

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

Para realizar uma atualização em todos os elementos da array incorporados de cada documento que corresponda à sua query, use o operador posicional filtrado $[<identifier>].

O operador posicional filtrado $[<identifier>] especifica os elementos de array correspondentes no documento de atualização. Para identificar quais elementos de array devem corresponder, emparelhe este operador com <identifier> em um objeto arrayFilters.

O espaço reservado <identifier> representa um elemento do campo de array Você deve selecionar um valor para <identifier> que comece com uma letra minúscula e contenha apenas caracteres alfanuméricos.

Você pode usar um operador posicional filtrado em uma operação de atualização. Uma operação de atualização utiliza uma query, um documento de atualização e, opcionalmente, um objeto de opções como parâmetros.

As seguintes etapas descrevem como utilizar um operador posicional filtrado em uma operação de atualização:

  1. Formate seu documento de atualização da seguinte maneira:

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

    Este documento de atualização contém os seguintes espaços reservados:

    • $<operator>: O operador de atualização de array

    • <array>: A array no documento a ser atualizada

    • <identifier>: O identificador do operador posicional filtrado

    • <arrayField>: O campo no elemento da array <array> a ser atualizado

    • <updateParameter>: O valor que descreve a atualização

  2. Adicione os critérios correspondentes no objeto arrayFilters . Esse objeto é uma array de consultas que especifica quais elementos de array devem ser incluídos na atualização. Defina este objeto em um parâmetro options :

    arrayFilters: [
    { "<identifier>.<arrayField1>": <updateParameter1> },
    { "<identifier>.<arrayField2>": <updateParameter2> },
    ...
    ]
  3. Passe a query, o documento de atualização e as opções para um método de atualização. O seguinte código de amostra mostra como chamar o método updateOne() com estes parâmetros:

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

Este exemplo usa os seguintes documentos de exemplo, que descrevem listas de compras para receitas específicas, para mostrar como atualizar determinados elementos de array correspondentes:

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

Suponha que você queira aumentar a quantidade de itens que você compra para uma receita em sua ida ao supermercado "11/12/2023". Você deseja dobrar a quantidade se o item atender a todos os critérios a seguir:

  • O item é para a receita de "Fried rice".

  • O nome do item não inclui a palavra "oil".

Para duplicar o valor de quantity nas entradas de array correspondentes, use o operador posicional filtrado como mostrado no seguinte código:

// Query for all documents where date is the string "11/12/2023"
const query = { date: "11/12/2023" };
// For each matched document, change the quantity of items to 2
const updateDocument = {
$mul: { "items.$[i].quantity": 2 }
};
// Update only non-oil items used for fried rice
const options = {
arrayFilters: [
{
"i.recipe": "Fried rice",
"i.item": { $not: { $regex: "oil" } },
}
]
};
// Execute the update operation
const result = await myColl.updateOne(query, updateDocument, options);

A atualização multiplicou o valor quantity por 2 para itens que corresponderam aos critérios. O item "Sesame oil" não corresponde aos critérios no objeto arrayFilters e, portanto, foi excluído da atualização. Os seguintes documentos refletem estas alterações:

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

Voltar

Modificar documentos