Docs Menu
Docs Home
/ /

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

MongoDB con controladores

Esta página documenta una mongosh . Para ver el método equivalente en un driver de MongoDB, se debe consultar la página correspondiente al lenguaje de programación:

C#Java SyncNode.jsPyMongoCC++GoJava RSKotlin CoroutineKotlin SyncPHPMongoidRubyRustScala
db.collection.findOneAndUpdate( filter, update, options )

Actualiza un único documento en función de los criterios filter y sort.

Tip

Novedades en la 8.0 versión: El updateOne() El método incluye una sort opción para actualizar el primer documento en un orden de clasificación especificado por el usuario.

Devuelve:Devuelve el documento original por defecto. Devuelve el documento actualizado si returnNewDocument está configurado en true o returnDocument está configurado en after.

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.

El método findOneAndUpdate() tiene la siguiente forma:

db.collection.findOneAndUpdate(
<filter>,
<update document or aggregation pipeline>,
{
writeConcern: <document>,
projection: <document>,
sort: <document>,
maxTimeMS: <number>,
upsert: <boolean>,
returnDocument: <string>,
returnNewDocument: <boolean>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
}
)

El método findOneAndUpdate() toma los siguientes parámetros:

Parameter
Tipo
Descripción

filter

Documento

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

Para actualizar el primer documento devuelto en la colección, especifique un documento vacío { }.

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

Si el campo de query no es un documento, la operación devuelve un error.

Si ningún documento coincide con filter, no se actualizará ningún documento.

update

documento o arreglo

El documento de actualización o una pipeline de agregació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.

{ w: <value>, j: <boolean>, wtimeout: <number> }

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.

projection

Documento

Opcional. Un subconjunto de campos que se deben devolver.

Para devolver todos los campos en el documento devuelto, omita este parámetro.

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

sort

Documento

Opcional. Especifica un orden de clasificación para los documentos que coinciden con el filter.

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

Consulte cursor.sort().

maxTimeMS

Número

Opcional. Especifica un límite de tiempo en milisegundos dentro del cual debe completarse la operación. Genera un error si se supera el límite.

upsert

booleano

Opcional. Cuando true, findOneAndUpdate() puede:

  • Crea un nuevo documento si no hay documentos que coincidan con filter. Para obtener más detalles, consulte comportamiento de inserción. Devuelve null después de insertar el nuevo documento, a menos que returnNewDocument sea true.

  • Actualiza un solo documento que coincida con filter.

Para evitar múltiples upserts, asegúrate de que el/los campo(s) filter estén indexados de forma única.

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

returnDocument

string

Opcional. A partir de mongosh 0.13.2, returnDocument es una alternativa a returnNewDocument. Si ambas opciones están configuradas, returnDocument tiene prioridad.

returnDocument: "before" devuelve el documento original. returnDocument: "after" devuelve el documento actualizado.

returnNewDocument

booleano

Opcional. Cuando true, devuelve el documento actualizado en lugar del documento original.

Se establece por defecto en false.

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.

Para las escrituras reintentables, el método findOneAndUpdate() debe copiar todo el documento en una colección paralela especial para cada nodo de un set de réplicas antes de realizar la actualización. Esto puede hacer que findOneAndUpdate() sea una operación costosa cuando se trata de documentos grandes o sets de réplicas grandes.

Nuevo en la versión 8.0: Para actualizar el primer documento en un orden definido por el usuario con un mejor rendimiento, utilice el método db.collection.updateOne() con la opción sort.

db.collection.findOneAndUpdate() actualiza el primer documento coincidente en la colección con el filter. Si ningún documento coincide con filter, no se actualizará ningún documento.

El parámetro sort puede utilizarse para seleccionar qué documento se actualiza.

Importante

Consistencia del lenguaje

Como parte de hacer que la proyección de find() y findAndModify() sea coherente con la etapa de agregación de $project,

El parámetro projection acepta un documento con el siguiente formato:

{ field1 : <value>, field2 : <value> ... }
Proyección
Descripción

<field>: <1 or true>

Especifica la inclusión de un campo. Si especificas un entero distinto de cero para el valor de proyección, la operación trata el valor como true.

<field>: <0 or false>

Especifica la exclusión de un campo.

"<field>.$": <1 or true>

Utiliza el operador de proyección de arreglo $ para devolver el primer elemento que coincide con la condición de query en el campo de arreglo. Si especificas un entero distinto de cero para el valor de proyección, la operación trata el valor como true.

No disponible para las vistas.

<field>: <array projection>

Utiliza los operadores de proyección de arreglos ($elemMatch, $slice) para especificar los elementos del arreglo que se deben incluir.

No disponible para las vistas.

<field>: <aggregation expression>

Especifica el valor del campo proyectado.

Con el uso de expresiones y sintaxis de agregación, incluido el uso de literales y variables de agregación, se pueden proyectar campos nuevos o proyectar campos existentes con valores nuevos.

  • Si se especifica un literal no numérico, no booleano (como una cadena de caracteres, un arreglo o una expresión de operador) para el valor de proyección, el campo se proyecta con el nuevo valor, por ejemplo:

    • { field: [ 1, 2, 3, "$someExistingField" ] }

    • { field: "New String Value" }

    • { field: { status: "Active", total: { $sum: "$existingArray" } } }

  • Para proyectar un valor literal para un campo, utiliza la expresión de agregación $literal, por ejemplo:

    • { field: { $literal: 5 } }

    • { field: { $literal: true } }

    • { field: { $literal: { fieldWithValue0: 0, fieldWithValue1: 1 } } }

Para campos en documentos incrustados, puedes especificar el campo mediante:

  • notación de puntos, por ejemplo "field.nestedfield": <value>

  • formulario anidado, por ejemplo { field: { nestedfield: <value> } }

El campo _id se incluye por defecto en los documentos devueltos, a menos que especifiques explícitamente _id: 0 en la proyección para suprimir el campo.

Una projection no puede contener ambas especificaciones de inclusión y exclusión, con la excepción del campo _id:

  • En las proyecciones que incluyen explícitamente campos, el campo _id es el único campo que puedes excluir explícitamente.

  • En las proyecciones que excluyen explícitamente campos, el campo _id es el único campo que puedes incluir explícitamente; sin embargo, el campo _id se incluye por defecto.

Para obtener más información sobre la proyección, consulte también:

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 modificar el valor de clave de fragmentación existente con db.collection.findOneAndUpdate():

  • 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 la clave de partición. Para usar db.collection.findOneAndUpdate() a fin de establecer la clave de partición faltante del 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:

db.collection.findOneAndUpdate() 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.findOneAndUpdate() 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.findOneAndUpdate() actualiza con éxito un documento, la operación añade una entrada en el OpLog (registro de operaciones). Si la operación falla o no encuentra un documento para actualizar, no se agrega una entrada en el oplog.

La colección grades contiene documentos similares a los siguientes:

{ _id: 6305, name : "A. MacDyver", "assignment" : 5, "points" : 24 },
{ _id: 6308, name : "B. Batlock", "assignment" : 3, "points" : 22 },
{ _id: 6312, name : "M. Tagnum", "assignment" : 5, "points" : 30 },
{ _id: 6319, name : "R. Stiles", "assignment" : 2, "points" : 12 },
{ _id: 6322, name : "A. MacDyver", "assignment" : 2, "points" : 14 },
{ _id: 6234, name : "R. Stiles", "assignment" : 1, "points" : 10 }

La siguiente operación encuentra el primer documento donde name : R. Stiles e incrementa la puntuación en 5:

db.grades.findOneAndUpdate(
{ "name" : "R. Stiles" },
{ $inc: { "points" : 5 } }
)

La operación devuelve el documento original antes de la actualización:

{ _id: 6319, name: "R. Stiles", "assignment" : 2, "points" : 12 }

Si returnNewDocument fuera cierto, la operación devolvería el documento actualizado en su lugar.

La colección grades contiene documentos similares a los siguientes:

{ _id: 6305, name : "A. MacDyver", "assignment" : 5, "points" : 24 },
{ _id: 6308, name : "B. Batlock", "assignment" : 3, "points" : 22 },
{ _id: 6312, name : "M. Tagnum", "assignment" : 5, "points" : 30 },
{ _id: 6319, name : "R. Stiles", "assignment" : 2, "points" : 12 },
{ _id: 6322, name : "A. MacDyver", "assignment" : 2, "points" : 14 },
{ _id: 6234, name : "R. Stiles", "assignment" : 1, "points" : 10 }

La siguiente operación actualiza un documento donde name : "A. MacDyver". La operación ordena los documentos coincidentes por points en orden ascendente para actualizar el documento coincidente con la menor cantidad de puntos.

db.grades.findOneAndUpdate(
{ "name" : "A. MacDyver" },
{ $inc : { "points" : 5 } },
{ sort : { "points" : 1 } }
)

La operación devuelve el documento original antes de la actualización:

{ _id: 6322, name: "A. MacDyver", "assignment" : 2, "points" : 14 }

En la siguiente operación, se utiliza proyección para mostrar solo los campos _id, points y assignment en el documento devuelto:

db.grades.findOneAndUpdate(
{ "name" : "A. MacDyver" },
{ $inc : { "points" : 5 } },
{ sort : { "points" : 1 }, projection: { "assignment" : 1, "points" : 1 } }
)

La operación devuelve el documento original con solo los campos especificados en el documento projection y el campo _id, ya que no se suprimió explícitamente (_id: 0) en el documento de proyección.

{ "_id" : 6322, "assignment" : 2, "points" : 14 }

En la siguiente operación, se establece un límite de tiempo de 5 ms para completar la actualización:

try {
db.grades.findOneAndUpdate(
{ "name" : "A. MacDyver" },
{ $inc : { "points" : 5 } },
{ sort: { "points" : 1 }, maxTimeMS : 5 };
);
}
catch(e){
print(e);
}

Si la operación excede el límite de tiempo, devuelve:

Error: findAndModifyFailed failed: { "ok" : 0, "errmsg" : "operation exceeded time limit", "code" : 50 }

En la siguiente operación, se utiliza el campo upsert para insertar el documento para actualizar si nada coincide con filter:

try {
db.grades.findOneAndUpdate(
{ "name" : "A.B. Abracus" },
{ $set: { "name" : "A.B. Abracus", "assignment" : 5}, $inc : { "points" : 5 } },
{ sort: { "points" : 1 }, upsert:true, returnNewDocument : true }
);
}
catch (e){
print(e);
}

La operación devuelve lo siguiente:

{
"_id" : ObjectId("5789249f1c49e39a8adc479a"),
"name" : "A.B. Abracus",
"assignment" : 5,
"points" : 5
}

Si returnNewDocument fuera falso, la operación devolvería null, ya que no hay un documento original para devolver.

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.myColl.findOneAndUpdate(
{ category: "cafe" },
{ $set: { status: "Updated" } },
{ collation: { locale: "fr", strength: 1 } }
);

La operación devuelve el siguiente documento:

{ "_id" : 1, "category" : "café", "status" : "A" }

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 modificar todos los elementos que sean mayores o iguales que 100 en el arreglo grades, utilizar el operador posicional filtrado $[<identifier>] con la opción arrayFilters en el método db.collection.findOneAndUpdate():

db.students.findOneAndUpdate(
{ grades: { $gte: 100 } },
{ $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 modificar el mean de todos los elementos en el arreglo grades donde la calificación es mayor o igual a 85.

db.students2.findOneAndUpdate(
{ _id : 1 },
{ $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 }
]
}

db.collection.findOneAndUpdate() 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.students2.findOneAndUpdate(
{ _id : 1 },
[ { $set: { "total" : { $sum: "$grades.grade" } } } ], // The $set stage is an alias for ``$addFields`` stage
{ returnNewDocument: 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.

La operación devuelve el documento actualizado:

{
"_id" : 1,
"grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" :85, "std" : 6 } ],
"total" : 250
}

Volver

db.collection.findOneAndReplace

En esta página