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

Actualizar elementos de arreglos en un documento con operadores posicionales de MQL

Puede utilizar operadores posicionales con el Languaje del Query de MongoDB (MQL) para actualizar documentos que contienen arreglos sin reemplazar el arreglo ni añadirle elementos.

Este tutorial presenta varios casos de uso de operadores posicionales dentro de MongoDB.

  • Install mongosh.

  • Conéctate a una implementación.

  • Usar mongosh para insertar documentos en una nueva colección en la base de datos test por defecto:

    db.employees.insertMany(
    [
    {
    _id: 'SF',
    engineering: [
    { name: 'Alice', email: 'missingEmail', salary: 100000 },
    { name: 'Bob', email: 'missingEmail', salary: 75000 }
    ],
    sales: [
    { name: 'Charlie', email: 'charlie@mail.com', salary: 90000, bonus: 1000 }
    ]
    },
    {
    _id: 'NYC',
    engineering: [
    { name: 'Dave', email: 'dave@mail.com', salary: 55000 },
    ],
    sales: [
    { name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 2000 },
    { name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 10000 }
    ]
    }
    ]
    );

Los siguientes ejemplos te muestran cómo:

Para actualizar solo la primera coincidencia dentro de un arreglo, utiliza el operador $. El operador $ actúa como un marcador de posición para actualizar el primer elemento coincidente.

El siguiente ejemplo utiliza el método updateOne() con los operadores $ y $set para actualizar el primer correo electrónico que tenga el valor missingEmail en el arreglo engineering por alice@mail.com.

1db.employees.updateOne(
2 { "engineering.email": "missingEmail" },
3 { "$set": { "engineering.$.email": "alice@mail.com" } }
4);

Utilice el método find() para confirmar la actualización del correo electrónico de Alice.

db.employees.find()
[
{
_id: 'SF',
engineering: [
{ name: 'Alice', email: 'alice@mail.com', salary: 100000 },
{ name: 'Bob', email: 'missingEmail', salary: 75000 }
],
sales: [
{ name: 'Charlie', email: 'charlie@mail.com', salary: 90000, bonus: 1000 }
]
},
{
_id: 'NYC',
engineering: [
{ name: 'Dave', email: 'dave@mail.com', salary: 55000 }
],
sales: [
{ name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 2000 },
{ name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 10000 }
]
}
]

Como se muestra en el ejemplo anterior, después de filtrar para los documentos que tienen un elemento de arreglo con el campo engineering.email establecido en missingEmail, el operador $ sólo actualiza la primera coincidencia que cumple con el filtro.

Para actualizar un elemento en particular, se puede usar el operador $elemMatch.

El siguiente ejemplo usa el $elemMatch operador y el $ operador para actualizar el email de Bob a "bob@mail.com".

1db.employees.updateOne(
2 { engineering: { $elemMatch: { name: "Bob", email: "missingEmail" } } },
3 { $set: { "engineering.$.email": "bob@mail.com" } }
4);

Utilice el método find() para confirmar la actualización del correo electrónico de Bob.

db.employees.find(
{ "engineering": { $elemMatch: { name: "Bob" } } },
{ "engineering.$": 1, _id: 0 }
);
[
{
engineering: [ { name: 'Bob', email: 'bob@mail.com', salary: 75000 } ]
}
]

Para actualizar cada elemento de un arreglo con una sola operación, utiliza el operador $[].

Considera un caso en el que deseas otorgar una bonificación adicional de $2,000 a tus empleados de ventas en Nueva York. Puede usar el método updateMany() con el operador $[] y el operador $inc para aumentar todos los campos bonus dentro del arreglo sales en el documento NYC en 2000.

1db.employees.updateMany(
2 { "_id": "NYC" },
3 { "$inc": { "sales.$[].bonus": 2000 } }
4);

Utiliza el método find() para actualizar los campos bonus para los empleados del equipo de ventas de Nueva York.

db.employees.find(
{ _id: "NYC" },
{ sales: 1, _id: 0 }
);
[
{
sales: [
{ name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 4000 },
{ name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 12000 }
]
}
]

Para actualizar varios elementos del arreglo en una sola operación sin un exceso de código del lado del cliente acompañado de una operación de reemplazo, utiliza el $[<identifier>] operador. El operador $[<identifier>] actúa como un marcador de posición para actualizar todos los elementos que coincidan con una condición arrayFilters.

Considera el caso en el que quieres actualizar el salario de empleados específicos si cumplen con una serie de condiciones. Puede utilizar el método updateMany() con el operador $[<identifier>] para realizar esta tarea.

1db.employees.updateMany(
2 {},
3 {
4 "$set": {
5 "engineering.$[elemX].salary": 95000,
6 "sales.$[elemY].salary": 75000
7 }
8 },
9 {
10 "arrayFilters": [
11 { "elemX.name": "Bob", "elemX.salary": 75000 },
12 { "elemY.name": "Ed", "elemY.salary": 50000, }
13 ]
14 }
15);

En el ejemplo anterior, el primer parámetro es una coincidencia vacía, para evaluar todos los documentos de la colección.

elemX y elemY representan dos arrayFilters:diferentes

  • Para que coincida con elemX, un objeto arreglo debe tener un campo name de Bob y un salary de 75000.

  • Para que coincida con elemY, un objeto arreglo debe tener un campo name de Ed y un salary de 50000.

Si un elemento de arreglo en el documento coincide con el filtro elemX, entonces updateMany() establece el campo salary del objeto en 95000. Si un elemento del arreglo coincide con el filtro elemY, entonces updateMany() establece el campo salary para el objeto en 75000. Si un filtro no coincide, la operación de $set correspondiente no se activa.

Utiliza el método find() para confirmar la actualización del salario de Bob porque cumple con ambas condiciones de elemX.

db.employees.find(
{ "engineering.name": "Bob" },
{ engineering: { $elemMatch: { name: "Bob" } }, _id: 0 }
);
[
{
engineering: [
{ name: "Bob", email: "bob@mail.com", salary: 95000 }
]
}
]

Utiliza el método find() para confirmar que la actualización del salario de Ed no tuvo éxito porque no cumple con ninguna de las condiciones de elemX ni de elemY.

db.employees.find(
{ "sales.name": "Ed" },
{ sales: { $elemMatch: { name: "Ed" } }, _id: 0 }
);
[
{
sales: [
{ name: "Ed", email: "ed@mail.com", salary: 99000, bonus: 4000 }
]
}
]

Este tutorial te enseña algunos de los operadores posicionales dentro del Lenguaje de Consultas de MongoDB (MQL). Estos operadores son útiles cuando se trabaja con arreglos porque evitan que se tengan que realizar reemplazos completos en el arreglo o manipulaciones extensas del lado del cliente. Para obtener más información sobre MQL, consulta cómo empezar con Atlas.

Para obtener más información sobre los operadores de actualización en MongoDB, consulta Operadores de actualización.

Volver

Métodos

En esta página