Docs Menu
Docs Home
/ /
Consultar y escribir

findAndModify (comando de base de datos)

findAndModify

El comando findAndModify actualiza y devuelve un único documento. Por defecto, el documento devuelto no incluye las modificaciones realizadas en la actualización. Para devolver el documento con las modificaciones realizadas en la actualización, use la opción new.

Tip

mongoshEn, este comando también se puede ejecutar a través del db.collection.findAndModify() método auxiliar.

Los métodos asistente son convenientes para usuarios de mongosh, pero es posible que no proporcionen el mismo nivel de información que los comandos de base de datos. En los casos en que no se necesite la conveniencia o se requieran campos de retorno adicionales, utiliza el comando de base de datos.

Este comando 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 comando tiene la siguiente sintaxis:

db.runCommand(
{
findAndModify: <collection-name>,
query: <document>,
sort: <document>,
remove: <boolean>,
update: <document or aggregation pipeline>,
new: <boolean>,
fields: <document>,
upsert: <boolean>,
bypassDocumentValidation: <boolean>,
writeConcern: <document>,
maxTimeMS: <integer>,
collation: <document>,
arrayFilters: <array>,
hint: <document|string>,
comment: <any>,
let: <document> // Added in MongoDB 5.0
}
)

El comando toma los siguientes campos:

Campo
Tipo
Descripción

query

Documento

Opcional. Los criterios de selección para la modificación. El query campo utiliza los mismos selectores de consulta que el db.collection.find() método. Aunque la consulta puede coincidir con varios documentos, findAndModify solo seleccionará un documento para actualizar.

Si no se especifica, el valor es por defecto un documento vacío.

Si el argumento del query no es un documento, la operación arroja un error.

sort

Documento

Opcional. Determina qué documento actualiza la Operación si el query selecciona varios documentos. findAndModify actualiza el primer documento en el orden de clasificación especificado por este argumento.

Si el argumento de orden no es un documento, la operación genera un error.

MongoDB no almacena documentos en una colección en un orden específico. Al ordenar en un campo que contiene valores duplicados, los documentos que contienen esos valores pueden ser devueltos en cualquier orden.

Si se desea un orden de clasificación coherente, se debe incluir al menos un campo en la clasificación que contenga valores únicos. La forma más sencilla de garantizar esto es incluir el campo _id en la query de ordenación.

Consultar coherencia de ordenación para obtener más información.

remove

booleano

Debe especificar el campo remove o el campo update. Remueve el documento especificado en el campo query. Configúrelo en true para remover el documento seleccionado . El valor por defecto es false.

update

documento o arreglo

Debe especificar el campo remove o el campo update. Realiza una actualización del documento seleccionado.

new

booleano

Opcional. Cuando true, devuelve el documento actualizado, en lugar del original. El valor por defecto es false.

fields

Documento

Opcional. Un subconjunto de campos para devolver. El fields documento especifica la inclusión de un campo con,1 como en:. fields: { <field1>: 1, <field2>: 1, ... } Consulte Proyección.

Si el argumento del campo no es un documento, la operación genera un error.

upsert

booleano

Opcional. Se utiliza en conjunto con el campo update.

Cuando true, findAndModify ya sea:

  • 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.

Para evitar múltiples inserciones, asegúrese de que los campos de query estén indexados de forma única. Consulte Inserción con un índice único para ver un ejemplo.

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

bypassDocumentValidation

booleano

Opcional. Le permite a findAndModify omitir la validación de esquema durante la operación. Esto permite actualizar documentos que no cumplen con los requisitos de validación.

writeConcern

Documento

Opcional. Un documento que expresa el nivel de confirmación de escritura. Omite el uso del nivel de confirmación de escritura por defecto.

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.

maxTimeMS

non-negative integer

Opcional.

Especifica un límite de tiempo en milisegundos. Si no especifica un valor para maxTimeMS, las operaciones no agotarán el tiempo de espera. Un valor de 0 especifica explícitamente el comportamiento por defecto sin límites.

MongoDB finaliza las operaciones que exceden su límite de tiempo asignado utilizando el mismo mecanismo que db.killOp(). MongoDB solo termina una operación en uno de sus puntos de interrupción designados.

findAndModify

string

La colección contra la que ejecutar el comando.

collation

Documento

Opcional.

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.

arrayFilters

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

Para ver ejemplos, consulte Operaciones de actualización de arreglos con arrayFilters.

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

hint

documento o cadena

Opcional. Un documento o cadena que especifica el índice que se utilizará para query admitir.

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 ver un ejemplo, consulte Especificar hint para findAndModify operaciones.

comment

any

Opcional. Un comentario proporcionado por el usuario para adjuntar a este comando. Una vez configurado, este comentario aparece junto a los registros de este comando en las siguientes ubicaciones:

Un comentario puede ser de cualquier tipo BSON válido (string, objeto, arreglo, etc.).

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 comando devuelve un documento con los siguientes findAndModify campos:

Campo
Tipo
Descripción

value

Documento

Contiene el valor devuelto por el comando. Consulte para obtener más value detalles.

lastErrorObject

Documento

Contiene información sobre documentos actualizados. Consulte para obtener más lastErrorObject detalles.

ok

Número

Contiene el estado de ejecución del comando. 1 en caso de éxito o 0 si ocurrió un error.

El documento incrustado lastErrorObject contiene los siguientes campos:

Campo
Tipo
Descripción

updatedExisting

booleano

Contiene true si se realiza una operación update:

  • Se actualizó un documento existente.

  • Encontré el documento, pero ya estaba en el estado de destino deseado, por lo que no se produjo ninguna actualización.

upserted

Documento

Contiene el ObjectId del documento insertado si una update operación con upsert: true resultó en un nuevo documento.

Para las operaciones remove, value contiene el documento eliminado si la consulta encuentra un documento. Si la consulta no encuentra un documento para eliminar, value contiene null.

Para las operaciones update, el documento incrustado value contiene lo siguiente:

  • Si el parámetro new no está establecido o es false:

    • el documento antes de la modificación si el query coincide con un documento;

    • de lo contrario, null.

  • Si new es true:

    • el documento actualizado si el query devuelve una coincidencia;

    • el documento insertado si upsert: true y ningún documento coincide con el query;

    • de lo contrario, null.

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.runCommand(
{
findAndModify: "people",
query: { name: "Andy" },
update: { $inc: { score: 1 } },
upsert: true
}
)

Si todas las operaciones findAndModify 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 findAndModify 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 findAndModify operaciones ahora muestran el siguiente comportamiento:

  • Exactamente una findAndModify operación insertará exitosamente un nuevo documento.

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

    Para que otras operaciones de findAndModify 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).

Para usar findAndModify en una colección fragmentada:

  • Si solo apunta a una partición, puede usar una clave de partición parcial en el campo query o

  • Puede proporcionar una condición de igualdad en una clave de partición completa en el campo query.

Es posible que a los documentos de una colección fragmentada les falten 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.

Advertencia

Los documentos en colecciones particionadas pueden no tener los campos de clave de partición. Toma precauciones para evitar remover accidentalmente la clave de partición al cambiar el valor de clave de partición de un documento.

Para actualizar el valor de clave de partición existente con findAndModify:

  • Debes ejecutar en un mongos. No emitas la operación directamente en la partición.

  • Usted debe ejecutar ya sea en una transacción o como una escritura reintentable.

  • Debe incluir un filtro de igualdad en la clave de partición completa.

Los documentos en una colección particionada pueden carecer de los campos de clave de partición. Para utilizar findAndModify para establecer la clave de partición que falta en el documento:

  • Debes ejecutar en un mongos. No emitas la operación directamente en la partición.

  • Debe ejecutar ya sea en una transacción o como una escritura reintentable si el nuevo valor de la clave de partición no es null.

  • Debe incluir un filtro de igualdad en la clave de partición completa.

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:

El comando findAndModify añade compatibilidad con la opción bypassDocumentValidation, que le permite omitir la validación de esquema al insertar o actualizar documentos en una colección con reglas de validación.

Al actualizar un documento, findAndModify y el método updateOne() operan de manera diferente:

  • Si varios documentos cumplen con los criterios de actualización, para findAndModify, puedes especificar un sort que proporcione cierto control sobre qué documento actualizar.

    updateOne() actualiza el primer documento que coincide.

  • Por defecto, findAndModify devuelve un objeto que contiene la versión premodificada del documento, así como el estado de la operación. Para obtener el documento actualizado, utilice la new opción.

    El método updateOne() devuelve un objeto WriteResult() que contiene el estado de la operación.

    Para devolver el documento actualizado, utilice el método find(). Sin embargo, es posible que otras actualizaciones hayan modificado el documento entre su actualización y la recuperación del documento. Además, si la actualización modificó solo un documento, pero varios documentos coincidieron, necesitará usar lógica adicional para identificar el documento actualizado.

Al modificar un solo documento, tanto el método findAndModify como updateOne() actualizan el documento atómicamente. Consulte Atomicidad y transacciones para obtener más información sobre las interacciones y el orden de las operaciones de estos métodos.

findAndModify 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.

findAndModify 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.

El siguiente comando actualiza un documento existente en la colección people donde el documento coincide con los criterios query:

db.runCommand(
{
findAndModify: "people",
query: { name: "Tom", state: "active", rating: { $gt: 10 } },
sort: { rating: 1 },
update: { $inc: { score: 1 } }
}
)

Este comando realiza las siguientes acciones:

  1. El query encuentra un documento en la colección people donde el campo name tiene el valor Tom, el campo state tiene el valor active y el campo rating tiene un valor de greater than 10.

  2. El sort ordena los resultados de la consulta en orden ascendente. Si varios documentos cumplen la condición query, el comando seleccionará para su modificación el primer documento ordenado por este sort.

  3. El update increments el valor del score campo 1 por.

  4. El comando devuelve un documento con los siguientes campos:

    • El campo lastErrorObject que contiene los detalles del comando, incluido el campo updatedExisting que es true, y

    • El campo value que contiene el documento original (es decir, anterior a la modificación) seleccionado para esta actualización:

      {
      "lastErrorObject" : {
      "connectionId" : 1,
      "updatedExisting" : true,
      "n" : 1,
      "syncMillis" : 0,
      "writtenTo" : null,
      "err" : null,
      "ok" : 1
      },
      value" : {
      "_id" : ObjectId("54f62d2885e4be1f982b9c9c"),
      "name" : "Tom",
      "state" : "active",
      "rating" : 100,
      "score" : 5
      },
      "ok" : 1
      }

Para devolver el documento actualizado en el campo value, agregue la opción new:true al comando.

Si ningún documento coincide con la condición query, el comando devuelve un documento que contiene null en el campo value:

{ "value" : null, "ok" : 1 }

mongosh y muchos controladores proporcionan un método auxiliar. Con el auxiliar del shell, esta operación previa puede adoptar la siguiente findAndModify() forma:

db.people.findAndModify( {
query: { name: "Tom", state: "active", rating: { $gt: 10 } },
sort: { rating: 1 },
update: { $inc: { score: 1 } }
} );

Sin embargo, el método auxiliar de shell solo devuelve el documento sin modificar findAndModify() o,new si true es, el documento actualizado.

{
"_id" : ObjectId("54f62d2885e4be1f982b9c9c"),
"name" : "Tom",
"state" : "active",
"rating" : 100,
"score" : 5
}

El siguiente comando incluye findAndModify la upsert: true opción para la update operación para actualizar un documento coincidente o, si no existe ningún documento coincidente, crear un nuevo documento:

db.runCommand(
{
findAndModify: "people",
query: { name: "Gus", state: "active", rating: 100 },
sort: { rating: 1 },
update: { $inc: { score: 1 } },
upsert: true
}
)

Si el comando encuentra un documento coincidente, realiza una actualización.

Si el comando no encuentra un documento coincidente, la operación update con upsert: true genera una inserción y devuelve un documento con los siguientes campos:

  • El campo lastErrorObject que contiene los detalles del comando, incluido el campo upserted que contiene el valor _id del documento recién insertado, y

  • El campo value que contiene null.

{
"value" : null,
"lastErrorObject" : {
"updatedExisting" : false,
"n" : 1,
"upserted" : ObjectId("54f62c8bc85d4472eadea26f")
},
"ok" : 1
}

El siguiente comando findAndModify incluye upsert: true las opciones new:true y. El comando actualiza un documento coincidente y devuelve el documento actualizado o, si no existe ningún documento coincidente, inserta un documento y devuelve el nuevo documento insertado en el value campo.

En el siguiente ejemplo, ningún documento de la colección people cumple con la condición query:

db.runCommand(
{
findAndModify: "people",
query: { name: "Pascal", state: "active", rating: 25 },
sort: { rating: 1 },
update: { $inc: { score: 1 } },
upsert: true,
new: true
}
)

El comando devuelve el documento recién insertado en el campo value:

{
"lastErrorObject" : {
"connectionId" : 1,
"updatedExisting" : false,
"upserted" : ObjectId("54f62bbfc85d4472eadea26d"),
"n" : 1,
"syncMillis" : 0,
"writtenTo" : null,
"err" : null,
"ok" : 1
},
"value" : {
"_id" : ObjectId("54f62bbfc85d4472eadea26d"),
"name" : "Pascal",
"rating" : 25,
"state" : "active",
"score" : 1
},
"ok" : 1
}

Al incluir una especificación sort en el campo rating, el siguiente ejemplo remueve de la colección people un único documento que tiene el valor state de active y el rating más bajo entre los documentos coincidentes:

db.runCommand(
{
findAndModify: "people",
query: { state: "active" },
sort: { rating: 1 },
remove: true
}
)

El comando devuelve el documento eliminado:

{
"lastErrorObject" : {
"connectionId" : 1,
"n" : 1,
"syncMillis" : 0,
"writtenTo" : null,
"err" : null,
"ok" : 1
},
"value" : {
"_id" : ObjectId("54f62a6785e4be1f982b9c9b"),
"name" : "XYZ123",
"score" : 1,
"state" : "active",
"rating" : 3
},
"ok" : 1
}

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.

Una colección myColl tiene los siguientes documentos:

{ _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:

db.runCommand(
{
findAndModify: "myColl",
query: { category: "cafe", status: "a" },
sort: { category: 1 },
update: { $set: { status: "Updated" } },
collation: { locale: "fr", strength: 1 }
}
)

La operación devuelve el siguiente documento:

{
"lastErrorObject" : {
"updatedExisting" : true,
"n" : 1
},
"value" : {
"_id" : 1,
"category" : "café",
"status" : "A"
},
"ok" : 1
}

Nota

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

Al actualizar el campo de un arreglo, puede especificar arrayFilters que determinen qué elementos del arreglo actualizar.

Nota

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

Cree una colección 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 sean mayores o iguales a 100 en la grades matriz, utilice el operador posicional con $[<identifier>] la arrayFilters opción:

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

La operación actualiza el campo grades de un único documento y, tras 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, 110, 100 ] }

Nota

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

Cree una colección 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 }
]
}
] )

La siguiente operación encuentra un documento donde el campo _id es igual a 1 y utiliza el operador posicional filtrado $[<identifier>] con el arrayFilters para actualizar el mean de todos los elementos en el arreglo grades donde la calificación es mayor o igual a 85.

db.runCommand(
{
findAndModify: "students2",
query: { _id : 1 },
update: { $set: { "grades.$[elem].mean" : 100 } },
arrayFilters: [ { "elem.grade": { $gte: 85 } } ]
}
)

La operación actualiza el campo grades de un único documento y, tras la operación, la colección contiene 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" : 75, "std" : 6 },
{ "grade" : 87, "mean" : 90, "std" : 3 },
{ "grade" : 85, "mean" : 85, "std" : 4 }
]
}

findAndModify puede aceptar un pipeline de agregación para la actualización. El 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.

Por ejemplo, cree una colección 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 }
]
}
] )

La siguiente operación encuentra un documento donde el campo _id es igual a 1 y utiliza una canalización de agregación para calcular un nuevo campo total a partir del campo grades:

db.runCommand(
{
findAndModify: "students2",
query: { "_id" : 1 },
update: [ { $set: { "total" : { $sum: "$grades.grade" } } } ],
new: true
}
)

Nota

El $set utilizado en el pipeline se refiere a la etapa de agregación $set y no al operador de actualización $set.

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" : 90, "std" : 4 }, { "grade" : 85, "mean" :85, "std" : 6 } ],
"total" : 250
}
{
"_id" : 2,
"grades" : [ { "grade" : 90, "mean" : 75, "std" : 6 }, { "grade" : 87, "mean" : 90, "std" : 3 }, { "grade" : 85, "mean" : 85,"std" : 4 } ]
}

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

db.members.insertMany( [
{ "_id" : 1, "member" : "abc123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null },
{ "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" },
{ "_id" : 3, "member" : "lmn123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null },
{ "_id" : 4, "member" : "pqr123", "status" : "D", "points" : 20, "misc1" : "Deactivated", "misc2" : null },
{ "_id" : 5, "member" : "ijk123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null },
{ "_id" : 6, "member" : "cde123", "status" : "A", "points" : 86, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
] )

Cree los siguientes índices en la colección:

db.members.createIndex( { status: 1 } )
db.members.createIndex( { points: 1 } )

La siguiente operación sugiere explícitamente utilizar el índice { status: 1 }:

db.runCommand({
findAndModify: "members",
query: { "points": { $lte: 20 }, "status": "P" },
remove: true,
hint: { status: 1 }
})

Nota

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

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

db.runCommand(
{
explain: {
findAndModify: "members",
query: { "points": { $lte: 20 }, "status": "P" },
remove: true,
hint: { status: 1 }
},
verbosity: "queryPlanner"
}
)

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 una variable targetFlavor en let y utiliza la variable para cambiar el sabor del pastel de cereza a naranja:

db.cakeFlavors.runCommand( {
findAndModify: db.cakeFlavors.getName(),
query: { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } },
update: { flavor: "orange" },
let: { targetFlavor: "cherry" }
} )

Volver

buscar

En esta página