Definición
$[<identifier>]El operador posicional filtrado
$[<identifier>]identifica los elementos de la matriz que coinciden con las condicionesarrayFilterspara una operación de actualización, por ejemplodb.collection.updateMany()y.db.collection.findAndModify()Usado en conjunto con la opción
arrayFilters, el operador$[<identifier>]tiene la siguiente forma:{ <update operator>: { "<array>.$[<identifier>]" : value } }, { arrayFilters: [ { <identifier>: <condition> } ] } Utiliza junto con la opción
arrayFilterspara actualizar todos los elementos que coincidan con las condicionesarrayFiltersen el documento o documentos que coincidan con las condiciones del query. Por ejemplo:db.collection.updateMany( { <query conditions> }, { <update operator>: { "<array>.$[<identifier>]" : value } }, { arrayFilters: [ { <identifier>: <condition> } ] } ) Nota
El
<identifier>debe comenzar con una letra minúscula y contener solo caracteres alfanuméricos.Para ver un ejemplo, véase Actualizar todos los elementos de la matriz que coincidan con
arrayFilters.
Comportamiento
A partir de MongoDB 5.0, los operadores de actualización procesan los campos de documentos con nombres basados en cadenas en orden lexicográfico. Los campos con nombres numéricos se procesan en orden numérico. Consulta Comportamiento del operador de actualización para obtener más información.
Restricciones
La opción arrayFilters no puede incluir los siguientes operadores del query:
upsert
Si una operación de inserción da como resultado una inserción, la query debe incluir una coincidencia exacta en el campo del arreglo para poder utilizar $[<identifier>] en la instrucción de actualización.
Por ejemplo, la siguiente operación de inserción, que utiliza $[<identifier>] en el documento de actualización, especifica una condición de coincidencia exacta en el campo del arreglo:
db.collection.updateOne( { myArray: [ 0, 1 ] }, { $set: { "myArray.$[element]": 2 } }, { arrayFilters: [ { element: 0 } ], upsert: true } )
Si no existe tal documento, la operación resultaría en la inserción de un documento que se asemeja al siguiente:
{ "_id" : ObjectId(...), "myArray" : [ 2, 1 ] }
Si la operación de inserción no incluyó una coincidencia exacta y no se encontraron documentos coincidentes para actualizar, la operación de inserción generaría un error. Por ejemplo, las siguientes operaciones generarían un error si no se encontraran documentos coincidentes para actualizar:
db.array.updateOne( { }, { $set: { "myArray.$[element]": 10 } }, { arrayFilters: [ { element: 9 } ], upsert: true } )
La operación devolvería un error que se asemeja al siguiente:
MongoServerError: The path 'myArray' must exist in the document in order to apply array updates.
Arreglos anidados
El operador posicional filtrado $[<identifier>] puede utilizarse para el query que atraviesa más de un arreglo y arreglos anidados.
Para un ejemplo, consulta Actualizar arreglos anidados en conjunción con $[].
Ejemplos
Actualizar todos los elementos del arreglo que coincidan arrayFilters
Crear la colección students:
db.students.insertMany( [ { "_id" : 1, "grades" : [ 95, 92, 90 ] }, { "_id" : 2, "grades" : [ 98, 100, 102 ] }, { "_id" : 3, "grades" : [ 95, 110, 100 ] } ] )
Para actualizar todos los elementos que sean mayores o iguales a 100 en el arreglo grades, utiliza el operador posicional filtrado $[<identifier>] con el arrayFilters:
db.students.updateMany( { }, { $set: { "grades.$[element]" : 100 } }, { arrayFilters: [ { "element": { $gte: 100 } } ] } )
El Operador posicional $[<identifier>] actúa como un marcador de posición para todos los elementos en el campo del arreglo que coinciden con las condiciones especificadas en arrayFilters.
Después de la operación, la colección students contiene los siguientes documentos:
{ "_id" : 1, "grades" : [ 95, 92, 90 ] } { "_id" : 2, "grades" : [ 98, 100, 100 ] } { "_id" : 3, "grades" : [ 95, 100, 100 ] }
Actualizar todos los documentos que coinciden con arrayFilters en unamatriz
El operador $[<identifier>] facilita las actualizaciones de arreglos que contienen documentos incrustados. Para acceder a los campos en los documentos incrustados, utiliza la notación de puntos con el $[<identifier>].
db.collection.updateMany( { <query selector> }, { <update operator>: { "array.$[<identifier>].field" : value } }, { arrayFilters: [ { <identifier>: <condition> } } ] } )
Crear la colección students2:
db.students2.insertMany( [ { "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" : 85, "std" : 6 } ] }, { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 75, "std" : 6 }, { "grade" : 87, "mean" : 90, "std" : 3 }, { "grade" : 85, "mean" : 85, "std" : 4 } ] } ] )
Para modificar el valor del campo mean para todos los elementos en el arreglo grades donde la calificación es mayor o igual a 85, utilice el operador posicional $[<identifier>] y arrayFilters:
db.students2.updateMany( { }, { $set: { "grades.$[elem].mean" : 100 } }, { arrayFilters: [ { "elem.grade": { $gte: 85 } } ] } )
Después de la operación, la colección tiene los siguientes documentos:
{ "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 100, "std" : 4 }, { "grade" : 85, "mean" : 100, "std" : 6 } ] } { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 100, "std" : 6 }, { "grade" : 87, "mean" : 100, "std" : 3 }, { "grade" : 85, "mean" : 100, "std" : 4 } ] }
Actualizar todos los elementos del arreglo que coincidan con múltiples condiciones
Crear la colección students3:
db.students3.insertMany( [ { "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 100, "std" : 4 }, { "grade" : 85, "mean" : 100, "std" : 6 } ] }, { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 100, "std" : 6 }, { "grade" : 87, "mean" : 100, "std" : 3 }, { "grade" : 85, "mean" : 100, "std" : 4 } ] } ] )
Para modificar el valor del campo std para todos los elementos del arreglo grades donde tanto la calificación es mayor o igual a 80 como std es mayor o igual a 5, utiliza el operador posicional $[<identifier>] y arrayFilters:
db.students3.updateMany( { }, { $inc: { "grades.$[elem].std" : -1 } }, { arrayFilters: [ { "elem.grade": { $gte: 80 }, "elem.std": { $gte: 5 } } ] } )
Después de la operación, la colección tiene los siguientes documentos:
{ "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 5 }, { "grade" : 85, "mean" : 100, "std" : 4 }, { "grade" : 85, "mean" : 100, "std" : 5 } ] } { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 100, "std" : 5 }, { "grade" : 87, "mean" : 100, "std" : 3 }, { "grade" : 85, "mean" : 100, "std" : 4 } ] }
Actualizar los elementos del arreglo utilizando un operador de negación
Crear la colección alumni:
db.alumni.insertMany( [ { "_id": 1, "name": "Christine Franklin", "degrees": [ { "level": "Master" }, { "level": "Bachelor" } ], }, { "_id": 2, "name": "Reyansh Sengupta", "degrees": [ { "level": "Bachelor" } ], } ] )
Para modificar todos los elementos del arreglo degrees que no tienen "level": "Bachelor", utiliza la operación posicional $[<identifier>] con el operador del query $ne:
db.alumni.updateMany( { }, { $set : { "degrees.$[degree].gradcampaign" : 1 } }, { arrayFilters : [ {"degree.level" : { $ne: "Bachelor" } } ] } )
Después de la operación, la colección tiene los siguientes documentos:
{ _id: 1, name: 'Christine Franklin', degrees: [ { level: 'Master', gradcampaign: 1 }, { level: 'Bachelor' } ] }, { _id: 2, name: 'Reyansh Sengupta', degrees: [ { level: 'Bachelor' } ] }
Actualizar arreglos anidados en conjunto con $[]
El operador posicional filtrado$[<identifier>] , junto con todo el operador posicional $[], se puede utilizar para actualizar arreglos anidados.
Cree una colección students4 con el siguiente documento:
db.students4.insertOne( { "_id" : 1, "grades" : [ { type: "quiz", questions: [ 10, 8, 5 ] }, { type: "quiz", questions: [ 8, 9, 6 ] }, { type: "hw", questions: [ 5, 4, 3 ] }, { type: "exam", questions: [ 25, 10, 23, 0 ] }, ] } )
Lo siguiente actualiza los valores que son mayores o iguales a 8 en el arreglo anidado grades.questions si el campo asociado grades.type es quiz.
db.students4.updateMany( {}, { $inc: { "grades.$[t].questions.$[score]": 2 } }, { arrayFilters: [ { "t.type": "quiz" }, { "score": { $gte: 8 } } ] } )
Nota
No agregues espacios alrededor de los identificadores del arreglo. Si utilizas grades.$[ t ].questions.$[ score ] en el ejemplo anterior, el ejemplo falla.
Después de la operación, la colección tiene el siguiente documento:
{ "_id" : 1, "grades" : [ { "type" : "quiz", "questions" : [ 12, 10, 5 ] }, { "type" : "quiz", "questions" : [ 10, 11, 6 ] }, { "type" : "hw", "questions" : [ 5, 4, 3 ] }, { "type" : "exam", "questions" : [ 25, 10, 23, 0 ] } ] }
Para actualizar todos los valores que sean mayores o iguales a 8 en el arreglo anidado grades.questions, independientemente de type:
db.students4.updateMany( {}, { $inc: { "grades.$[].questions.$[score]": 2 } }, { arrayFilters: [ { "score": { $gte: 8 } } ] } )
Obtén más información
Para ejemplos que utilizan el operador $[<identifier>] para actualizar arreglos, consulta Actualizar elementos de arreglo en un documento con operadores posicionales de MQL.