Docs Menu
Docs Home
/ /
Colecciones

db.colección.actualizar() (método mongosh)

Importante

Método obsoleto de mongosh

db.collection.update(query, update, options)

Modifica un documento o varios documentos existentes en una colección. El método puede modificar campos específicos de un documento o de documentos existentes o reemplazar por completo un documento existente, dependiendo del parámetro de actualización.

Por defecto, el método db.collection.update() actualiza un único documento. Incluye la opción multi: true para actualizar todos los documentos que cumplan con los criterios de query.

Este método está disponible en implementaciones alojadas en los siguientes entornos:

  • MongoDB Atlas: El servicio totalmente gestionado para implementaciones de MongoDB en la nube

Nota

Este comando es compatible con todos los clústeres de MongoDB Atlas. Para obtener información sobre el soporte de Atlas para todos los comandos, consulte Comandos no compatibles.

  • MongoDB Enterprise: La versión basada en suscripción y autogestionada de MongoDB

  • MongoDB Community: La versión de MongoDB con código fuente disponible, de uso gratuito y autogestionada.

Modificado en la versión 5.0.

El método db.collection.update() tiene la siguiente forma:

db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string>,
let: <document> // Added in MongoDB 5.0
}
)

El método db.collection.update() toma los siguientes parámetros:

Parameter
Tipo
Descripción

Documento

Los criterios de selección para actualizar. Los mismos selectores query que en el método find() están disponibles.

Cuando ejecutas una update() con upsert: true y la query no coincide con ningún documento existente, MongoDB se negará a insertar un nuevo documento si la query especifica condiciones en el campo _id usando notación de puntos.

documento o pipeline

Las modificaciones que se deben aplicar puede ser una de las siguientes:

Contiene únicamente <field1>: <value1> pares.

Contiene únicamente las siguientes etapas de agregación:

Para obtener más detalles y ejemplos, consulta Entradas del Oplog.

booleano

Opcional. Cuando true, update() puede:

  • Crea un nuevo documento si no hay documentos que coincidan con query. Para más detalles, consulta comportamiento de inserción.

  • Actualiza un solo documento que coincida con query.

Si tanto upsert como multi son verdaderos y ningún documento coincide con el query, la operación de actualizar inserta solo un documento.

Para evitar múltiples inserciones, asegúrate de que los campos del query estén indexados de forma única. Consulta Inserción con valores duplicados como ejemplo.

Se establece por defecto en false, lo que no inserta un nuevo documento cuando no se encuentra ninguna coincidencia.

booleano

Opcional. Si se establece en true, actualiza varios documentos que cumplen con los criterios query. Si se establece en false, actualiza un documento. El valor por defecto es false. Para obtener más información, consulta Ejemplos para actualizar varios documentos.

Documento

Opcional. Un documento que expresa el nivel de confirmación de escritura (write concern). Omite para usar el nivel de confirmación de escritura (write concern) por defecto w: "majority".

No establezcas explícitamente el nivel de confirmación de escritura para la operación si se ejecuta en una transacción. Para usar el nivel de confirmación de escritura con transacciones, consulta Transacciones y nivel de confirmación de escritura.

Para un ejemplo usando writeConcern, consulta Anular el nivel de confirmación de escritura por defecto.

Documento

Opcional.

La intercalación permite a los usuarios especificar reglas propias del lenguaje para la comparación de strings, como reglas para el uso de mayúsculas y minúsculas y marcas de acento.

Para un ejemplo usando collation, consulta Especificar intercalación.

arreglo

Opcional. Un arreglo de documentos de filtro que determinan qué elementos del arreglo modificar para una operación de actualización en un campo de arreglo.

En el documento de actualización, utiliza el $[<identifier>] para definir un identificador que actualice solo aquellos elementos del arreglo que coincidan con el documento de filtro correspondiente en el arrayFilters.

Nota

No es posible tener un documento de filtro de arreglo para un identificador si el identificador no está incluido en el documento para actualizar.

Para obtener ejemplos, consulta Especificar arrayFilters para operaciones de actualización de arreglos.

Documento o string

Opcional. Un documento o string que especifica el índice que se utilizará para respaldar el predicado de query.

La opción puede tomar un documento de especificación de índice o la string de nombre de índice.

Si especifica un índice que no existe, la operación genera un error.

Para un ejemplo, consulta Especificar hint para las operaciones de actualización.

Documento

Opcional.

Especifica un documento que contiene una lista de variables. Esto le permite mejorar la legibilidad de los comandos al separar las variables del texto de la query.

La sintaxis del documento es:

{
<variable_name_1>: <expression_1>,
...,
<variable_name_n>: <expression_n>
}

La variable se establece en el valor devuelto por la expresión y no puede modificarse posteriormente.

Para acceder al valor de una variable en el comando, se debe usar el prefijo de doble signo de dólar ($$) junto con el nombre de la variable en la forma $$<variable_name>. Por ejemplo: $$targetTotal.

Para usar una variable para los resultados del filtro, debes acceder a la variable dentro del operador $expr.

Para un ejemplo completo usando let y variables, vea Uso de variables en let.

Nuevo en la versión 5.0.

El método devuelve un documento WriteResult que contiene el estado de la operación.

En las implementaciones que se ejecutan con authorization, el usuario debe tener acceso que incluya los siguientes privilegios:

  • update acción en las colecciones especificadas.

  • find acción en las colecciones especificadas.

  • insert acción en las colecciones especificadas si la operación produce una inserción.

El rol con funcionalidad incorporada readWrite proporciona los privilegios necesarios.

Si configuras multi: true, usa el método update() solo para operaciones idempotentes.

Intentar usar el operador $expr con la bandera de inserción configurada en true generará un error.

Para usar db.collection.update() con multi: false en una colección particionada, se debe incluir una coincidencia exacta en el campo _id o dirigirse a una única partición (por ejemplo, incluyendo la clave de partición).

Cuando el db.collection.update() realiza operaciones de actualización (y no operaciones de reemplazo de documentos), db.collection.update() puede dirigirse a varias particiones.

Tip

Las operaciones de reemplazo de documentos intentan apuntar a una única partición, primero utilizando el filtro de query. Si la operación no puede apuntar a una única partición mediante el filtro de query, entonces intenta apuntar mediante el documento de reemplazo.

En versiones anteriores, la operación intenta dirigirse utilizando el documento de reemplazo.

Para una db.collection.update() operación que incluya inserción: true y esté en una colección particionada, debes incluir la clave de partición completa en el filter:

  • Para una operación de actualización.

  • Para una operación de reemplazo de documento.

Sin embargo, a los documentos de una colección fragmentada pueden faltarles los campos de clave de fragmento. Para identificar un documento que no tenga la clave de fragmento, puede usar la null coincidencia de igualdad. Junto con otra condición de filtro (como en el _id campo). Por ejemplo:

{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key

Puede actualizarse el valor de clave de partición de un documento a menos que el campo de clave de partición sea el campo _id inmutable.

Para modificar el valor de clave de fragmentación existente con db.collection.update():

Tip

Dado que un valor de clave faltante se devuelve como parte de una coincidencia exacta nula, para evitar actualizar una clave con valor nulo, incluya condiciones de query adicionales (como en el campo _id) según corresponda.

Véase también upsert en una colección particionada.

Los documentos en una colección particionada pueden carecer de los campos de clave de partición. Para usar db.collection.update() para establecer la clave de partición faltante del documento, se debe ejecutar en un mongos. No realizar la operación directamente en la partición.

Además, se aplican los siguientes requisitos:

Tarea
Requisitos

Para configurar en null

  • Puedes especificar multi: true.

  • Requiere un filtro de igualdad en la clave de partición completa si upsert: true.

Para establecer en un valor que no sea null

  • Debe realizarse dentro de una transacción o como una escritura reintentable.

  • Debes especificar multi: false.

  • Requiere filtro de igualdad en la clave de partición completa si:

    • upsert: true, o

    • si se utiliza un documento de reemplazo y el nuevo valor de clave de fragmentación pertenece a una partición diferente.

Tip

Dado que un valor de clave faltante se devuelve como parte de una coincidencia exacta nula, para evitar actualizar una clave con valor nulo, incluya condiciones de query adicionales (como en el campo _id) según corresponda.

Véase también:

db.collection.update() puede usarse dentro de transacciones distribuidas.

Importante

En la mayoría de los casos, una transacción distribuida incurre en un costo de rendimiento mayor que las escrituras de documentos individuales, y la disponibilidad de transacciones distribuidas no debería ser un sustituto para un diseño de esquema efectivo. Para muchos casos, el modelo de datos desnormalizado (documento incrustado y matrices) seguirá siendo óptimo para tus datos y casos de uso. Es decir, en muchos casos, modelar tus datos de forma adecuada minimizará la necesidad de transacciones distribuidas.

Para consideraciones adicionales sobre el uso de transacciones (como el límite de tiempo de ejecución y el límite de tamaño del oplog), consulta también las consideraciones de producción.

Puedes crear colecciones e índices dentro de una transacción distribuida si la transacción no es una transacción de escritura entre particiones.

db.collection.update() con upsert: true puede ejecutarse en una colección existente o en una colección inexistente. Si se ejecuta en una colección que es inexistente, la operación crea la colección.

No establezcas explícitamente el nivel de confirmación de escritura para la operación si se ejecuta en una transacción. Para usar el nivel de confirmación de escritura con transacciones, consulta Transacciones y nivel de confirmación de escritura.

Si una operación db.collection.update() actualiza con éxito uno o más documentos, la operación añade una entrada en el oplog (registro de operaciones). Si la operación falla o no encuentra ningún documento para actualizar, la operación no agrega una entrada en el OpLog.

Las siguientes pestañas presentan una variedad de operaciones comunes de update().

En mongosh, crea una colección books que contenga los siguientes documentos. Este comando primero remueve todos los documentos previamente existentes de la colección books:

db.books.remove({});
db.books.insertMany([
{
"_id" : 1,
"item" : "TBD",
"stock" : 0,
"info" : { "publisher" : "1111", "pages" : 430 },
"tags" : [ "technology", "computer" ],
"ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "lmn", "rating" : 5 } ],
"reorder" : false
},
{
"_id" : 2,
"item" : "XYZ123",
"stock" : 15,
"info" : { "publisher" : "5555", "pages" : 150 },
"tags" : [ ],
"ratings" : [ { "by" : "xyz", "rating" : 5 } ],
"reorder" : false
}
]);

Si el <update> documento contiene modificadores del operador de actualizar, como aquellos que utilizan el modificador $set, entonces:

  • El documento <update> debe contener únicamente expresiones de operador de actualizar.

  • El método db.collection.update() actualiza únicamente los campos correspondientes en el documento.

    • Para actualizar un documento incrustado o un arreglo en su totalidad, especifica el valor de reemplazo para el campo.

    • Para actualizar campos particulares en un documento incrustado o en un arreglo, utilizar notación de puntos para especificar el campo.

db.books.update(
{ _id: 1 },
{
$inc: { stock: 5 },
$set: {
item: "ABC123",
"info.publisher": "2222",
tags: [ "software" ],
"ratings.1": { by: "xyz", rating: 3 }
}
}
)

En esta operación:

  • El parámetro <query> de { _id: 1 } especifica cuál documento se debe actualizar

  • el operador $inc incrementa el campo stock, y

  • el operador $set reemplaza el valor de

    • item campo

    • publisher campo en el documento incrustado info,

    • tags campo, y

    • segundo elemento en el ratings arreglo.

El documento actualizado es el siguiente:

{
"_id" : 1,
"item" : "ABC123",
"stock" : 5,
"info" : { "publisher" : "2222", "pages" : 430 },
"tags" : [ "software" ],
"ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "xyz", "rating" : 3 } ],
"reorder" : false
}

Esta operación corresponde a la siguiente instrucción SQL:

UPDATE books
SET stock = stock + 5
item = "ABC123"
publisher = 2222
pages = 430
tags = "software"
rating_authors = "ijk,xyz"
rating_values = "4,3"
WHERE _id = 1

Nota

Si el parámetro query coincidiera con varios documentos, esta operación solo actualizaría uno. Para actualizar varios documentos, debe establecer la opción multi en true.

Tip

$set,, $inc Operadores de actualización, notación de punto

La siguiente operación utiliza el operador $push de actualización para añadir un nuevo objeto al arreglo ratings.

db.books.update(
{ _id: 2 },
{
$push: { ratings: { "by" : "jkl", "rating" : 2 } }
}
)

El documento actualizado es el siguiente:

{
"_id" : 2,
"item" : "XYZ123",
"stock" : 15,
"info" : {
"publisher" : "5555",
"pages" : 150
},
"tags" : [ ],
"ratings" : [
{ "by" : "xyz", "rating" : 5 },
{ "by" : "jkl", "rating" : 2 }
],
"reorder" : false
}

La siguiente operación utiliza el operador $unset para eliminar el campo tags del documento con { _id: 1 }.

db.books.update( { _id: 1 }, { $unset: { tags: 1 } } )

El documento actualizado es el siguiente:

{
"_id" : 1,
"item" : "TBD",
"stock" : 0,
"info" : {
"publisher" : "1111",
"pages" : 430
},
"ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "lmn", "rating" : 5 } ],
"reorder" : false
}

No hay un equivalente directo en SQL para $unset, sin embargo, $unset es similar al siguiente comando SQL que remueve el campo tags de la tabla books:

ALTER TABLE books
DROP COLUMN tags

Si multi se establece en true, el método db.collection.update() actualiza todos los documentos que cumplen con los criterios <query>. La operación de actualización multi puede intercalarse con otras operaciones de lectura/guardado.

La siguiente operación establece el campo reorder a true para todos los documentos donde stock es menor o igual a 10. Si el campo reorder no existe en los documentos coincidentes, el operador $set agrega el campo con el valor especificado.

db.books.update(
{ stock: { $lte: 10 } },
{ $set: { reorder: true } },
{ multi: true }
)

Los documentos resultantes en la colección son los siguientes:

[
{
"_id" : 1,
"item" : "ABC123",
"stock" : 5,
"info" : {
"publisher" : "2222",
"pages" : 430
},
"ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "xyz", "rating" : 3 } ],
"reorder" : true
}
{
"_id" : 2,
"item" : "XYZ123",
"stock" : 10,
"info" : { "publisher" : "2255", "pages" : 150 },
"tags" : [ "baking", "cooking" ],
"reorder" : true
}
]

Esta operación corresponde a la siguiente instrucción SQL:

UPDATE books
SET reorder=true
WHERE stock <= 10

Nota

No se puede especificar multi: true al realizar un reemplazo, es decir, cuando el <update> documento contiene solo field:value expresiones.

Tip

Cuando especificas la opción inserción: true:

Si especificas upsert: true en una colección particionada, debes incluir la clave de partición completa en el filter. Para obtener información adicional sobre el comportamiento db.collection.update() en una colección particionada, consulta Colecciones particionadas.

Las siguientes pestañas muestran una variedad de usos del modificador upsert con update().

Si ningún documento coincide con los criterios de query y el parámetro <update> es un documento de reemplazo (es decir, contiene solo pares de campo y valor), la actualización inserta un nuevo documento con los campos y valores del documento de reemplazo.

  • Si especificas un campo _id en el parámetro de query o en el documento de reemplazo, MongoDB utiliza ese campo _id en el documento insertado.

  • Si no especificas un campo _id ni en el parámetro de query ni en el documento de reemplazo, MongoDB añade el campo _id con un valor de ObjectId generado aleatoriamente.

    Nota

    No pueden especificarse diferentes valores de campo de _id en el parámetro de query y en el documento de reemplazo. De lo contrario, la operación falla.

Por ejemplo, la siguiente actualización configura la opción inserción a true:

db.books.update(
{ item: "ZZZ135" }, // Query parameter
{ $set:
{
item: "ZZZ135", stock: 5, tags: [ "database" ] // Replacement document
}
},
{ upsert: true } // Options
)

Si ningún documento coincide con el parámetro <query>, la operación de actualización inserta un documento que contiene únicamente el documento de reemplazo. Debido a que no se especificó ningún campo _id en el documento de reemplazo o en el documento de query, la operación crea un nuevo ObjectId único para el campo _id del nuevo documento. Se puede ver el upsert reflejado en el WriteResult de la operación:

WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("5da78973835b2f1c75347a83")
})

La operación inserta el siguiente documento en la colección books (el valor de ObjectId será diferente):

{
"_id" : ObjectId("5da78973835b2f1c75347a83"),
"item" : "ZZZ135",
"stock" : 5,
"tags" : [ "database" ]
}

Si ningún documento coincide con los criterios de query y el parámetro <update> es un documento con expresiones de operadores de actualización, entonces la operación crea un documento base a partir de las cláusulas de igualdad en el parámetro <query> y aplica las expresiones del parámetro <update>.

Las operaciones de comparación del <query> no se incluirán en el nuevo documento. Si el nuevo documento no incluye el campo _id, MongoDB añade el campo _id con un valor ObjectId.

Por ejemplo, la siguiente actualización configura la opción inserción a true:

db.books.update(
{ item: "BLP921" }, // Query parameter
{ // Update document
$set: { reorder: false },
$setOnInsert: { stock: 10 }
},
{ upsert: true } // Options
)

Si ningún documento coincide con la condición del query, la operación inserta el siguiente documento (su valor de ObjectId será diferente):

{
"_id" : ObjectId("5da79019835b2f1c75348a0a"),
"item" : "BLP921",
"reorder" : false,
"stock" : 10
}

Si el parámetro <update> es un pipeline de agregación, la actualización crea un documento base a partir de las cláusulas de igualdad en el parámetro <query> y luego aplica el pipeline al documento para crear el documento a insertar. Si el nuevo documento no incluye el campo _id, MongoDB añade el campo _id con un valor de tipo ObjectId.

Por ejemplo, la siguiente operación inserción: true especifica un pipeline de agregación que utiliza

  • la etapa $replaceRoot que puede proporcionar un comportamiento algo similar al de una expresión de operador de actualización $setOnInsert,

  • la etapa $set que puede proporcionar un comportamiento similar a la expresión del operador de actualización $set,

  • la variable de agregación NOW, que se resuelve a la fecha y hora actuales y puede proporcionar un comportamiento similar a la expresión del operador para actualizar $currentDate.

db.books.update(
{ item: "MRQ014", ratings: [2, 5, 3] }, // Query parameter
[ // Aggregation pipeline
{ $replaceRoot: { newRoot: { $mergeObjects: [ { stock: 0 }, "$$ROOT" ] } } },
{ $set: { avgRating: { $avg: "$ratings" }, tags: [ "fiction", "murder" ], lastModified: "$$NOW" } }
],
{ upsert: true } // Options
)

Si ningún documento coincide con el parámetro <query>, la operación inserta el siguiente documento en la colección books (el valor de ObjectId será diferente):

{
"_id" : ObjectId("5e2921e0b4c550aad59d1ba9"),
"stock" : 0,
"item" : "MRQ014",
"ratings" : [ 2, 5, 3 ],
"avgRating" : 3.3333333333333335,
"tags" : [ "fiction", "murder" ],
"lastModified" : ISODate("2020-01-23T04:32:32.951Z")
}

Tip

Para obtener ejemplos adicionales de actualizaciones utilizando canalizaciones de agregación, consulta Actualizar con pipeline de agregación.

Desde mongosh, inserte los siguientes documentos en una colección de books:

db.books.insertMany( [
{
_id: 5,
item: "RQM909",
stock: 18,
info: { publisher: "0000", pages: 170 },
reorder: true
},
{
_id: 6,
item: "EFG222",
stock: 15,
info: { publisher: "1111", pages: 72 },
reorder: true
}
] )

La siguiente operación especifica tanto la opción multi como la opción upsert. Si existen documentos coincidentes, la operación actualiza todos los documentos coincidentes. Si no existen documentos coincidentes, la operación inserta un nuevo documento.

db.books.update(
{ stock: { $gte: 10 } }, // Query parameter
{ // Update document
$set: { reorder: false, tags: [ "literature", "translated" ] }
},
{ upsert: true, multi: true } // Options
)

La operación actualiza todos los documentos que coincidan y da como resultado lo siguiente:

{
"_id" : 5,
"item" : "RQM909",
"stock" : 18,
"info" : { "publisher" : "0000", "pages" : 170 },
"reorder" : false,
"tags" : [ "literature", "translated" ]
}
{
"_id" : 6,
"item" : "EFG222",
"stock" : 15,
"info" : { "publisher" : "1111", "pages" : 72 },
"reorder" : false,
"tags" : [ "literature", "translated" ]
}

Si la colección no tuviera ningún documento coincidente, la operación resultaría en la inserción de un único documento utilizando los campos de las especificaciones <query> y <update>. Por ejemplo, considere la siguiente operación:

db.books.update(
{ "info.publisher": "Self-Published" }, // Query parameter
{ // Update document
$set: { reorder: false, tags: [ "literature", "hardcover" ], stock: 25 }
},
{ upsert: true, multi: true } // Options
)

La operación inserta el siguiente documento en la colección books (el valor de ObjectId será diferente):

{
"_id" : ObjectId("5db337934f670d584b6ca8e0"),
"info" : { "publisher" : "Self-Published" },
"reorder" : false,
"stock" : 25,
"tags" : [ "literature", "hardcover" ]
}

Cuando se ejecuta un update() con upsert: true y el query no coincide con ningún documento existente, MongoDB se negará a insertar un nuevo documento si el query especifica condiciones en el campo _id usando notación de puntos.

Esta restricción asegura que el orden de los campos incrustados en el documento _id esté bien definido y no dependa del orden especificado en el query.

Si intentas insertar un documento de esta manera, MongoDB generará un error. Por ejemplo, considera la siguiente operación de actualización. Dado que la operación de actualizar especifica upsert:true y el query especifica condiciones en el campo _id utilizando la notación de puntos, la actualización resultará en un error al construir el documento para insertar.

db.collection.update(
{ "_id.name": "Robert Frost", "_id.uid": 0 }, // Query parameter
{ $set:
{
"categories": [ "poet", "playwright" ] // Replacement document
}
},
{ upsert: true } // Options
)

El WriteResult de la operación devuelve el siguiente error:

WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 111,
"errmsg" : "field at '_id' must be exactly specified, field at sub-path '_id.name'found"
}
})

Los upserts pueden crear documentos duplicados, a menos que haya un índice único para evitar duplicados.

Considere un ejemplo en el que no existe ningún documento con el nombre Andy y varios clientes emiten el siguiente comando aproximadamente al mismo tiempo:

db.people.update(
{ name: "Andy" },
{ $inc: { score: 1 } },
{
upsert: true,
multi: true
}
)

Si todas las operaciones update() terminan la fase de query antes de que algún cliente inserte correctamente los datos y no hay un índice único en el campo name, cada operación update() puede ocasionar una inserción, creando múltiples documentos con name: Andy.

Un índice único en el campo name asegura que solo se cree un documento. Con un índice único en su lugar, las múltiples update() operaciones ahora muestran el siguiente comportamiento:

  • Exactamente una update() operación insertará exitosamente un nuevo documento.

  • Otras update() operaciones actualizan el documento recién insertado o fallan debido a una colisión de clave única.

    Para que otras operaciones de update() actualicen el documento recién insertado, todas las siguientes condiciones deben cumplirse:

    • La colección objetivo tiene un índice único que causaría un error de clave duplicada.

    • La operación de actualización no es updateMany o multi es false.

    • La condición de coincidencia de actualización es:

      • Un único predicado de igualdad. Por ejemplo { "fieldA" : "valueA" }

      • Un AND lógico de predicados de igualdad. Por ejemplo { "fieldA" : "valueA", "fieldB" : "valueB" }

    • Los campos del predicado de igualdad coinciden con los campos del patrón de clave del índice único.

    • La operación de actualización no modifica ningún campo en el patrón de clave de índice único.

La siguiente tabla muestra ejemplos de operaciones de upsert que, cuando ocurre una colisión de clave, se actualizan o fallan.

Patrón de clave de índice único
Operación de actualización
Resultado
{ name : 1 }
db.people.updateOne(
{ name: "Andy" },
{ $inc: { score: 1 } },
{ upsert: true }
)

El campo score del documento coincidente se incrementa en 1.

{ name : 1 }
db.people.updateOne(
{ name: { $ne: "Joe" } },
{ $set: { name: "Andy" } },
{ upsert: true }
)

La operación falla porque modifica el campo en el patrón de clave del índice único (name).

{ name : 1 }
db.people.updateOne(
{ name: "Andy", email: "andy@xyz.com" },
{ $set: { active: false } },
{ upsert: true }
)

La operación falla porque los campos del predicado de igualdad (name, email) no coinciden con el campo clave del índice (name).

El método db.collection.update() puede aceptar una pipeline de agregación [ <stage1>, <stage2>, ... ] que especifica las modificaciones a realizar. La pipeline puede constar de las siguientes etapas:

El uso de un pipeline de agregación permite una instrucción de actualización más expresiva, como expresar actualizaciones condicionales basadas en los valores actuales de los campos o actualizar un campo con el valor de otros campos.

Crea una colección students con los siguientes documentos:

db.students.insertMany( [
{ "_id" : 1, "student" : "Skye", "points" : 75, "commentsSemester1" : "great at math", "commentsSemester2" : "loses temper", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") },
{ "_id" : 2, "students" : "Elizabeth", "points" : 60, "commentsSemester1" : "well behaved", "commentsSemester2" : "needs improvement", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }
] )

Suponga que, en lugar de los campos commentsSemester1 y commentsSemester2 separados, desea reunirlos en un nuevo campo comments. La siguiente operación de actualización utiliza una canalización de agregación para:

  • añade el nuevo campo comments y establece el campo lastUpdate.

  • eliminar los campos commentsSemester1 y commentsSemester2 de todos los documentos en la colección.

db.members.update(
{ },
[
{ $set: { comments: [ "$commentsSemester1", "$commentsSemester2" ], lastUpdate: "$$NOW" } },
{ $unset: [ "commentsSemester1", "commentsSemester2" ] }
],
{ multi: true }
)

Nota

La $set y $unset utilizadas en la pipeline se refieren a las etapas de agregación $set y $unset respectivamente, y no a los operadores de actualización $set y $unset.

Primera etapa

La etapa $set:

  • crea un nuevo campo de arreglo comments cuyos elementos son el contenido actual de los campos commentsSemester1 y commentsSemester2 y

  • establece el campo lastUpdate al valor de la variable de agregación NOW. La variable de agregación NOW se resuelve al valor actual de la fecha y hora y permanece igual a lo largo de toda la pipeline de agregación. Para acceder a las variables de agregación, prefija la variable con signos double de dólar $$ y enciérrela entre comillas.

Segunda etapa
La etapa $unset remueve los campos commentsSemester1 y commentsSemester2.

Después del comando, la colección contiene los siguientes documentos:

{ "_id" : 1, "student" : "Skye", "status" : "Modified", "points" : 75, "lastUpdate" : ISODate("2020-01-23T05:11:45.784Z"), "comments" : [ "great at math", "loses temper" ] }
{ "_id" : 2, "student" : "Elizabeth", "status" : "Modified", "points" : 60, "lastUpdate" : ISODate("2020-01-23T05:11:45.784Z"), "comments" : [ "well behaved", "needs improvement" ] }

Crea una colección students3 con los siguientes documentos:

db.students3.insertMany( [
{ "_id" : 1, "tests" : [ 95, 92, 90 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") },
{ "_id" : 2, "tests" : [ 94, 88, 90 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") },
{ "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }
] )

Al utilizar un pipeline de agregación, puedes actualizar los documentos con el promedio de calificaciones calculado y la calificación en letras.

db.students3.update(
{ },
[
{ $set: { average : { $trunc: [ { $avg: "$tests" }, 0 ] }, lastUpdate: "$$NOW" } },
{ $set: { grade: { $switch: {
branches: [
{ case: { $gte: [ "$average", 90 ] }, then: "A" },
{ case: { $gte: [ "$average", 80 ] }, then: "B" },
{ case: { $gte: [ "$average", 70 ] }, then: "C" },
{ case: { $gte: [ "$average", 60 ] }, then: "D" }
],
default: "F"
} } } }
],
{ multi: true }
)

Nota

El $set utilizado en la pipeline se refiere a la etapa de agregación $set, y no a los operadores de actualizar $set.

Primera etapa

La etapa $set:

  • calcula un nuevo campo average basado en el promedio del campo tests. Consulta $avg para obtener más información sobre el operador de agregación $avg y $trunc para obtener más información sobre el operador de agregación de truncamiento $trunc.

  • establece el campo lastUpdate al valor de la variable de agregación NOW. La variable de agregación NOW se resuelve al valor actual de la fecha y hora y permanece igual a lo largo de toda la pipeline de agregación. Para acceder a las variables de agregación, prefija la variable con signos double de dólar $$ y enciérrela entre comillas.

Segunda etapa
La etapa $set calcula un nuevo campo grade basado en el campo average calculado en la etapa anterior. Consulta $switch para obtener más información sobre el operador de agregación $switch.

Después del comando, la colección contiene los siguientes documentos:

{ "_id" : 1, "tests" : [ 95, 92, 90 ], "lastUpdate" : ISODate("2020-01-24T17:29:35.340Z"), "average" : 92, "grade" : "A" }
{ "_id" : 2, "tests" : [ 94, 88, 90 ], "lastUpdate" : ISODate("2020-01-24T17:29:35.340Z"), "average" : 90, "grade" : "A" }
{ "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2020-01-24T17:29:35.340Z"), "average" : 75, "grade" : "C" }

En el documento de actualización, usa el operador posicional filtrado $[<identifier>] para definir un identificador, al que luego puedes hacer referencia en los documentos de filtro de arreglo. No puedes tener un documento de filtro de arreglo para un identificador si dicho identificador no está incluido en el documento de actualización.

El <identifier> debe comenzar con una letra minúscula y contener solo caracteres alfanuméricos.

Puedes incluir el mismo identificador varias veces en el documento de actualización; sin embargo, para cada identificador distinto ($[identifier]) en el documento de actualización, debes especificar exactamente un documento de filtro de arreglo correspondiente. Es decir, no puedes especificar múltiples documentos de filtro de arreglo para el mismo identificador. Por ejemplo, si la instrucción de actualizar incluye el identificador x (posiblemente varias veces), no puedes especificar lo siguiente para arrayFilters que incluya dos documentos de filtro separados para x:

// INVALID
[
{ "x.a": { $gt: 85 } },
{ "x.b": { $gt: 80 } }
]

Sin embargo, se pueden especificar condiciones compuestas sobre el mismo identificador en un único documento de filtro, como en los siguientes ejemplos:

// Example 1
[
{ $or: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 2
[
{ $and: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 3
[
{ "x.a": { $gt: 85 }, "x.b": { $gt: 80 } }
]

arrayFilters no está disponible para actualizaciones que utilizan un pipeline de agregación.

Para actualizar todos los elementos del arreglo que coincidan con un criterio específico, utiliza el parámetro arrayFilters.

En mongosh, crea una colección de students con los siguientes documentos:

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 son mayores o iguales a 100 en el arreglo grades, utiliza el operador posicional filtrado $[<identifier>] con la opción arrayFilters:

db.students.update(
{ grades: { $gte: 100 } },
{ $set: { "grades.$[element]" : 100 } },
{
multi: true,
arrayFilters: [ { "element": { $gte: 100 } } ]
}
)

Después de la operación, la colección contiene los siguientes documentos:

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 100 ] }
{ "_id" : 3, "grades" : [ 95, 100, 100 ] }

También se puede utilizar el parámetro arrayFilters para actualizar campos específicos de documentos dentro de un arreglo de documentos.

En mongosh, crea una colección de students2 con los siguientes documentos:

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 del arreglo grades, donde la calificación sea mayor o igual a 85, utiliza el operador posicional filtrado $[<identifier>] con arrayFilters:

db.students2.update(
{ },
{ $set: { "grades.$[elem].mean" : 100 } },
{
multi: true,
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 }
]
}

En mongosh, crea una colección de newStudents con los siguientes documentos:

db.newStudents.insertMany( [
{ "_id" : 1, "student" : "Richard", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null },
{ "_id" : 2, "student" : "Jane", "grade" : "A", "points" : 60, "comments1" : "well behaved", "comments2" : "fantastic student" },
{ "_id" : 3, "student" : "Ronan", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null },
{ "_id" : 4, "student" : "Noah", "grade" : "D", "points" : 20, "comments1" : "needs improvement", "comments2" : null },
{ "_id" : 5, "student" : "Adam", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null },
{ "_id" : 6, "student" : "Henry", "grade" : "A", "points" : 86, "comments1" : "fantastic student", "comments2" : "well behaved" }
] )

Cree el siguiente índice en la colección:

db.newStudents.createIndex( { grade: 1 } )

La siguiente operación de actualización indica explícitamente usar el índice {grade: 1 }:

db.newStudents.update(
{ points: { $lte: 20 }, grade: "F" }, // Query parameter
{ $set: { comments1: "failed class" } }, // Update document
{ multi: true, hint: { grade: 1 } } // Options
)

Nota

Si especifica un índice que no existe, la operación genera un error.

El comando de actualización devuelve lo siguiente:

WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })

Para ver el índice utilizado, ejecuta explain en la operación:

db.newStudents.explain().update(
{ "points": { $lte: 20 }, "grade": "F" },
{ $set: { "comments1": "failed class" } },
{ multi: true, hint: { grade: 1 } }
)

El db.collection.explain().update() no modifica los documentos.

Nuevo en la versión 5.0.

Para definir variables a las que puedes acceder en otros lugares del comando, utiliza la opción let.

Nota

Para filtrar los resultados usando una variable, debes acceder a la variable dentro del operador $expr.

Cree una colección cakeFlavors:

db.cakeFlavors.insertMany( [
{ _id: 1, flavor: "chocolate" },
{ _id: 2, flavor: "strawberry" },
{ _id: 3, flavor: "cherry" }
] )

El siguiente ejemplo define las variables targetFlavor y newFlavor en let y utiliza las variables para cambiar el sabor del pastel de cereza a naranja:

db.cakeFlavors.update(
{ $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } },
[ { $set: { flavor: "$$newFlavor" } } ],
{ let : { targetFlavor: "cherry", newFlavor: "orange" } }
)

La siguiente operación a un set de réplicas especifica un nivel de confirmación de escritura (write concern) de w: 2 con un wtimeout de 5000 milisegundos. Esta operación regresa después de que el guardado se propaga tanto al primario como a un secundario, o expira después de 5 segundos.

db.books.update(
{ stock: { $lte: 10 } },
{ $set: { reorder: true } },
{
multi: true,
writeConcern: { w: 2, wtimeout: 5000 }
}
)

Cambiado en la versión 8.1.2.

Cuando db.collection.update() se ejecuta en mongos en un clúster fragmentado, siempre se informa de un writeConcernError en la respuesta, incluso cuando se producen uno o más errores adicionales. En versiones anteriores, otros errores a veces causaban que db.collection.update() no reportara errores de nivel de confirmación de escritura.

Por ejemplo, si un documento no supera la validación, activando un error DocumentValidationFailed, y también ocurre un error de nivel de confirmación de escritura, tanto el error DocumentValidationFailed como el writeConcernError se devuelven en el campo de nivel superior de la respuesta.

Especifica la intercalación a utilizar para la operación.

La intercalación permite a los usuarios especificar reglas propias del lenguaje para la comparación de strings, como reglas para el uso de mayúsculas y minúsculas y marcas de acento.

La opción de intercalación tiene la siguiente sintaxis:

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

Al especificar la intercalación, el campo locale es obligatorio; todos los demás campos de intercalación son opcionales. Para las descripciones de los campos, consulta Documento de intercalación.

Si no se especifica la intercalación, pero la colección tiene una intercalación por defecto (ver db.createCollection()), la operación utiliza la intercalación especificada para la colección.

Si no se especifica ninguna intercalación para la colección o para las operaciones, MongoDB utiliza la comparación binaria simple usada en versiones anteriores para las comparaciones de strings.

No puedes especificar varias intercalaciones para una operación. Por ejemplo, no puedes especificar diferentes intercalaciones por campo, o si realizas una búsqueda con un ordenamiento, no puedes usar una intercalación para la búsqueda y otra para el ordenamiento.

En mongosh, cree una colección llamada myColl con los siguientes documentos:

db.myColl.insertMany( [
{ _id: 1, category: "café", status: "A" },
{ _id: 2, category: "cafe", status: "a" },
{ _id: 3, category: "cafE", status: "a" }
] )

La siguiente operación incluye la opción de intercalación y configura multi en true para actualizar todos los documentos coincidentes:

db.myColl.update(
{ category: "cafe" },
{ $set: { status: "Updated" } },
{
collation: { locale: "fr", strength: 1 },
multi: true
}
)

El resultado de la operación de guardar de la operación devuelve el siguiente documento, lo que indica que los tres documentos de la colección se actualizaron:

WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })

Después de la operación, la colección contiene los siguientes documentos:

{ "_id" : 1, "category" : "café", "status" : "Updated" }
{ "_id" : 2, "category" : "cafe", "status" : "Updated" }
{ "_id" : 3, "category" : "cafE", "status" : "Updated" }

El db.collection.update() método devuelve un WriteResult() objeto que contiene el estado de la operación. Al tener éxito, el objeto WriteResult() contiene el número de documentos que coincidieron con la condición del query, el número de documentos insertados por actualizar y el número de documentos modificados:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Si el método db.collection.update() encuentra errores de nivel de confirmación de escritura (write concern), los resultados incluyen el campo WriteResult.writeConcernError:

WriteResult({
"nMatched" : 1,
"nUpserted" : 0,
"nModified" : 1,
"writeConcernError": {
"code" : 64,
"errmsg" : "waiting for replication timed out",
"errInfo" : {
"wtimeout" : true,
"writeConcern" : {
"w" : "majority",
"wtimeout" : 100,
"provenance" : "getLastErrorDefaults"
}
}
})

La siguiente tabla explica los posibles valores de WriteResult.writeConcernError.provenance:

Origen
Descripción

clientSupplied

El nivel de confirmación de escritura se especificó en la aplicación.

customDefault

El nivel de confirmación de escritura se originó a partir de un valor por defecto personalizado. Vea setDefaultRWConcern.

getLastErrorDefaults

El nivel de confirmación de escritura se originó en el campo settings.getLastErrorDefaults del set de réplicas.

implicitDefault

El nivel de confirmación de escritura (write concern) se originó en el servidor en ausencia de todas las demás especificaciones de nivel de confirmación de escritura (write concern).

Si el método db.collection.update() encuentra un error que no es de nivel de confirmación de escritura (write concern), los resultados incluyen el campo WriteResult.writeError:

WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 7,
"errmsg" : "could not contact primary for replica set shard-a"
}
})

Volver

db.collection.unhideIndex

En esta página