Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Docs Menu

Actualizar arreglos en un documento

En esta guía, puedes aprender cómo usar los siguientes operadores de actualización de arreglos para modificar un arreglo incrustado dentro de un documento:

Para obtener una lista de los operadores de actualización de arreglos, consulte Operadores de actualización en la documentación del Manual del servidor.

Los operadores posicionales especifican qué elementos del arreglo actualizar. Puedes usar estos operadores para aplicar actualizaciones al primer elemento, a todos los elementos o a ciertos elementos de un arreglo que cumplan un criterio.

Para especificar elementos en un arreglo con operadores posicionales, utiliza la notación de puntos. La notación de puntos es una sintaxis de acceso a propiedades para navegar por los objetos BSON. Para obtener más información, ver notación de puntos.

Para actualizar el primer elemento del arreglo de cada documento que coincida con tu query, utiliza el operador posicional $.

El operador posicional $ hace referencia al arreglo coincidido por la query. No se puede utilizar este operador para hacer referencia a un arreglo anidado. Si quieres acceder a un arreglo anidado, utiliza el operador posicional filtrado.

Importante

No utilices el operador $ en una llamada upsert porque el driver trata $ como un nombre de campo en el documento de inserción.

Este ejemplo utiliza el siguiente documento de muestra para mostrar cómo actualizar el primer elemento coincidente del arreglo:

{
_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 del arreglo que coincide con una query.

La consulta coincide con los elementos en el arreglo 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 asemeja a lo siguiente:

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

El ejemplo incluye el campo entries.x en la query para que coincida con el arreglo al que el operador $ aplica una actualización. Si omite el campo entries.x de la query mientras utiliza el operador $ en una actualización, el driver no podrá identificar el arreglo correspondiente y mostrará el siguiente error:

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

Para realizar la actualización en todos los elementos de arreglo de cada documento que coincida con su query, use el operador posicional all $[].

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 remover el campo duration de todas las entradas del arreglo 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 asemejan a lo siguiente:

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

Para realizar una actualización en todos los elementos del arreglo anidado de cada documento que coincida con tu query, utiliza el operador posicional filtrado $[<identifier>].

El operador posicional filtrado $[<identifier>] especifica los elementos del arreglo que coinciden en el documento de actualización. Para identificar qué elementos del arreglo deben coincidir, combine 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.

Puedes usar un operador posicional filtrado en una operación de actualización. Una operación de actualización requiere una query, un documento de actualización y, opcionalmente, un objeto de opciones como parámetros.

Los pasos siguientes describen cómo usar un operador posicional filtrado en una operación de actualización:

  1. Da formato a tu 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 para actualizar el arreglo

    • <array>El arreglo en el documento que se va a actualizar

    • <identifier>El identificador para el operador posicional filtrado

    • <arrayField>: El campo del elemento del arreglo <array> a actualizar

    • <updateParameter>: El valor que describe la actualización.

  2. Agrega los criterios de coincidencia en el objeto arrayFilters. Este objeto es un conjunto de consultas que especifican qué elementos del arreglo se incluirán en la actualización. Establezca este objeto en un parámetro options:

    arrayFilters: [
    { "<identifier>.<arrayField1>": <updateParameter1> },
    { "<identifier>.<arrayField2>": <updateParameter2> },
    ...
    ]
  3. Pase la query, 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);

Este ejemplo utiliza los siguientes documentos de muestra, los cuales describen listas de compras para recetas específicas, para mostrar cómo actualizar ciertos elementos coincidentes de un arreglo:

{
_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 deseas aumentar la cantidad de artículos que compras para una receta durante tu viaje de compras a "11/12/2023". Quieres double la cantidad si el artículo cumple todos los siguientes criterios:

  • El artículo es para la receta "Fried rice".

  • El nombre del artículo no incluye la palabra "oil".

Para double el valor de quantity en las entradas del arreglo coincidentes, utiliza 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 elementos que coincidieron con los criterios. El elemento "Sesame oil" no cumplió con los criterios del 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" }
]
}