Overview
En esta guía, puede aprender a utilizar los siguientes operadores de actualización de matriz para modificar una matriz incrustada dentro de un documento:
Operador posicional:
$Todos los operadores posicionales:
$[]Operador posicional filtrado:
$[<identifier>]
Para obtener una lista de operadores de actualización de matrices,consulte Operadores de actualización en la documentación del Manual del servidor.
Especificación de elementos de matriz
Los operadores posicionales especifican qué elementos de la matriz se actualizarán. Puede usarlos para aplicar actualizaciones al primer elemento, a todos los elementos o a ciertos elementos de una matriz que cumplan un criterio.
Para especificar elementos en una matriz con operadores posicionales, utilice la notación de punto. Esta es una sintaxis de acceso a propiedades para navegar por objetos BSON. Para obtener más información, consulte la notación de punto.
El primer elemento coincidente de la matriz
Para actualizar el primer elemento de la matriz de cada documento que coincida con su consulta, utilice el operador posicional $.
El operador posicional $ hace referencia al array que coincide con la consulta. No se puede usar para hacer referencia a un array anidado. Si desea acceder a un array anidado, utilice el operador posicional filtrado.
Importante
No utilice el operador $ en una llamada upsert porque el controlador trata a $ como un nombre de campo en el documento de inserción.
Ejemplo
Este ejemplo utiliza el siguiente documento de muestra para mostrar cómo actualizar el primer elemento de la matriz coincidente:
{ _id: ..., entries: [ { x: false, y: 1 }, { x: "hello", y: 100 }, { x: "goodbye", y: 1000 } ] }
El siguiente código muestra cómo incrementar un valor en el primer elemento de la matriz que coincide con una consulta.
La consulta busca elementos en la matriz entries donde el valor de x es de tipo string. La actualización incrementa el valor de y en 33 en el primer elemento coincidente.
// 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);
Después de ejecutar la operación de actualización, el documento se parece al siguiente:
{ _id: ..., entries: [ { x: false, y: 1 }, { x: "hello", y: 133 }, { x: "goodbye", y: 1000 } ] }
El ejemplo incluye el campo entries.x en la consulta para que coincida con la matriz a la que el operador $ aplica una actualización. Si se omite el campo entries.x de la consulta al usar el operador $ en una actualización, el controlador no puede identificar la matriz coincidente y genera el siguiente error:
MongoServerError: The positional operator did not find the match needed from the query.
Coincidencia de todos los elementos del arreglo
Para realizar la actualización de todos los elementos de la matriz de cada documento que coincida con su consulta, utilice el operador posicional $[].
Ejemplo
Este ejemplo utiliza los siguientes documentos de muestra, que describen registros de llamadas telefónicas, para mostrar cómo actualizar todos los elementos coincidentes del arreglo:
{ _id: ..., date: "5/15/2023", calls: [ { time: "10:08 AM", caller: "Mom", duration: 67 }, { time: "04:11 PM", caller: "Dad", duration: 121 }, { time: "06:36 PM", caller: "Grandpa", duration: 13 } ] }, { _id: ..., date: "5/16/2023", calls: [ { time: "11:47 AM", caller: "Mom", duration: 4 }, ] }
El siguiente código muestra cómo eliminar el campo duration de todas las entradas de la matriz calls en el documento cuyo date es "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);
Después de ejecutar la operación de actualización, los documentos se parecen a los siguientes:
{ _id: ..., date: "5/15/2023", calls: [ { time: "10:08 AM", caller: "Mom" }, { time: "04:11 PM", caller: "Dad" }, { time: "06:36 PM", caller: "Grandpa" } ] }, { _id: ..., date: "5/16/2023", calls: [ { time: "11:47 AM", caller: "Mom", duration: 4 }, ] }
Coincidencia de múltiples elementos de una matriz
Para realizar una actualización de todos los elementos de la matriz incrustados de cada documento que coincida con su consulta, utilice el operador posicional filtrado $[<identifier>].
El operador posicional filtrado $[<identifier>] especifica los elementos de la matriz coincidentes en el documento de actualización. Para identificar los elementos de la matriz que se deben coincidir, empareje este operador con <identifier> en un objeto arrayFilters.
El placeholder <identifier> representa un elemento del campo de arreglo. Debe seleccionar un valor para <identifier> que comience con letra minúscula y contenga solo caracteres alfanuméricos.
Uso
Puede usar un operador posicional filtrado en una operación de actualización. Una operación de actualización toma como parámetros una consulta, un documento de actualización y, opcionalmente, un objeto de opciones.
Los siguientes pasos describen cómo utilizar un operador posicional filtrado en una operación de actualización:
Formatee su documento de actualización de la siguiente manera:
{ $<operator>: { "<array>.$[<identifier>].<arrayField>": <updateParameter> } } Este documento de actualización contiene los siguientes marcadores de posición:
$<operator>:El operador de actualización de matriz<array>:La matriz en el documento a actualizar<identifier>:El identificador del operador posicional filtrado<arrayField>:El campo en el elemento de la matriz<array>a actualizar<updateParameter>: El valor que describe la actualización.
Agregue los criterios coincidentes en el objeto
arrayFilters. Este objeto es una matriz de consultas que especifica qué elementos de la matriz se incluirán en la actualización. Establezca este objeto en un parámetrooptions:arrayFilters: [ { "<identifier>.<arrayField1>": <updateParameter1> }, { "<identifier>.<arrayField2>": <updateParameter2> }, ... ] Pase la consulta, el documento de actualización y las opciones a un método de actualización. El siguiente código de ejemplo muestra cómo llamar al método
updateOne()con estos parámetros:await myColl.updateOne(query, updateDocument, options);
Ejemplo
Este ejemplo utiliza los siguientes documentos de muestra, que describen listas de compras para recetas específicas, para mostrar cómo actualizar ciertos elementos de matriz coincidentes:
{ _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" } ] }
Supongamos que desea aumentar la cantidad de artículos que compra para una receta en su compra de comestibles "11/12/2023". Quiere duplicar la cantidad si el artículo cumple con todos los siguientes criterios:
El artículo es para la receta
"Fried rice".El nombre del artículo no incluye la palabra
"oil".
Para duplicar el valor quantity en las entradas de la matriz coincidentes, utilice el operador posicional filtrado como se muestra en el siguiente 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);
La actualización multiplicó el valor quantity por 2 para los elementos que cumplían los criterios. El elemento "Sesame oil" no cumplía los criterios en el objeto arrayFilters y, por lo tanto, se excluyó de la actualización. Los siguientes documentos reflejan estos cambios:
{ _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" } ] }