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.
Antes de comenzar
Instalar mongosh.
Conéctate a una implementación.
Usar
mongoshpara insertar documentos en una nueva colección en la base de datostestpor 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 } ] } ] );
Pasos
Los siguientes ejemplos te muestran cómo:
Utiliza el operador $ para actualizar la primera coincidencia en un arreglo
Usar el operador $ con $elemMatch para actualizar un elemento específico
Usa el operador $[] para actualizar todos los elementos de arreglo dentro de un documento
Utiliza el operador $ para actualizar la primera coincidencia en un arreglo
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.
1 db.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.
Usar el operador $ con $elemMatch para actualizar un elemento específico
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".
1 db.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 } ] } ]
Usa el operador $[] para actualizar todos los elementos de arreglo dentro de un documento
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.
1 db.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 } ] } ]
Utiliza el<identifier> operador $[] para actualizar los elementos que coincidan con una condición de filtro
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.
1 db.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 camponamedeBoby unsalaryde75000.Para que coincida con
elemY, un objeto arreglo debe tener un camponamedeEdy unsalaryde50000.
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 } ] } ]
Conclusión
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.