Docs Menu
Docs Home
/ /
Arreglos

$[<identifier>] (operador de actualización posicional filtrado)

$[<identifier>]

El operador posicional filtrado $[<identifier>] identifica los elementos de la matriz que coinciden con las condiciones arrayFilters para una operación de actualización, por ejemplo db.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 arrayFilters para actualizar todos los elementos que coincidan con las condiciones arrayFilters en 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, consulte Actualizar todos los elementos de arrayFilters la matriz que coincidan con.

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.

La opción arrayFilters no puede incluir los siguientes operadores del query:

  • $expr

  • $text

  • $where

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.

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 $[].

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 ] }

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 }
]
}

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 }
]
}

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' } ]
}

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 } } ] }
)

Tip

Para ejemplos que utilizan el operador $[<identifier>] para actualizar arreglos, consulta Actualizar elementos de arreglo en un documento con operadores posicionales de MQL.

Volver

$[]