sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB buscar y modificar ()

En MongoDB el db.collection.findAndModify() El método modifica y devuelve un único documento.

La collection part es el nombre de la colección con la que realizar la operación.

Ejemplo

Supongamos que tenemos una colección llamada pets que contiene los siguientes documentos:

{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }

Podemos usar db.collection.findAndModify() para modificar uno de esos documentos.

db.pets.findAndModify({
    query: { type: "Dog" },
    update: { type: "Cow" }
})

Resultado:

{ "_id" : 1, "name" : "Wag", "type" : "Dog" } 

Por defecto, devuelve el documento original (no la versión modificada).

Tenga en cuenta que solo se actualizó un perro, aunque hay dos perros en la colección.

Revisemos la colección.

db.pets.find()

Resultado:

{ "_id" : 1, "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }

Podemos ver que el primer documento ahora contiene una vaca en lugar de un perro. Sin embargo, también podemos ver que el campo del nombre del documento ha desaparecido.

Eso es porque, cuando pasa un documento a update argumento, db.collection.findAndModify() realiza un reemplazo.

Uso de un operador de actualización

Si quisiéramos actualizar un campo, pero dejar el resto del documento intacto, necesitaríamos incluir las expresiones relevantes del operador de actualización en nuestro documento.

Con la colección en su estado actual, realicemos otro findAndModify() operación en su contra, pero esta vez usaremos el $set operador de actualización para establecer solo el campo que queremos cambiar.

db.pets.findAndModify({
    query: { type: "Dog" },
    update: { $set: { type: "Horse" } }
})

Resultado:

{ "_id" : 2, "name" : "Bark", "type" : "Dog" }

Esta vez se actualizó el perro restante.

Echemos un vistazo a la colección.

db.pets.find()

Resultado:

{ "_id" : 1, "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Horse" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }

Esta vez se actualizó el campo relevante y el resto del documento permaneció intacto.

Devolver el Documento Modificado

De forma predeterminada, el documento original se devuelve cuando usa db.collection.findAndModify() .

Si prefiere que le devuelvan el documento modificado, use el new parámetro.

Por defecto, esto es new: false , lo que hace que se devuelva el documento original. Pero especificando new: true da como resultado que se devuelva el documento modificado.

Hagamos otra modificación, pero esta vez usaremos new: true .

db.pets.findAndModify({
    query: { name: "Meow" },
    update: { $set: { name: "Scratch" } },
    new: true
})

Resultado:

{ "_id" : 3, "name" : "Scratch", "type" : "Cat" }

Así que renombramos Meow Scratch y la salida refleja nuestros cambios.

Inserciones

Puede realizar upserts especificando upsert: true .

Un upsert es una opción que puede usar en las operaciones de actualización. Si el documento especificado no existe, se inserta uno nuevo. Si lo hace existe, el documento original se actualiza (y no se inserta ningún documento).

Ejemplo usando upsert: false

Aquí hay un ejemplo de intentar actualizar un documento inexistente cuando upsert: false .

db.pets.findAndModify({
    query: { _id: 4 },
    update: { _id: 4, name: "Fetch", type: "Dog" },
    new: true
})

Resultado:

null

El documento no existía en la colección, por lo que findAndModify() devolvió null . Aunque no especificamos upsert: false , sabemos que era falso porque ese es el valor predeterminado (es decir, ese es el valor que se usa cuando no especifica una opción upsert).

Si echamos otro vistazo a la colección, podemos ver que el documento no fue alterado.

db.pets.find()

Resultado:

{ "_id" : 1, "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Horse" }
{ "_id" : 3, "name" : "Scratch", "type" : "Cat" }

Ejemplo usando upsert: true

Ahora aquí está de nuevo, pero esta vez especificamos upsert: true .

db.pets.findAndModify({
    query: { _id: 4 },
    update: { _id: 4, name: "Fetch", type: "Dog" },
    new: true,
    upsert: true
})

Resultado:

{ "_id" : 4, "name" : "Fetch", "type" : "Dog" }

Esta vez se altera un nuevo documento y vemos el documento alterado como salida (porque especificamos new: true ).

Revisemos la colección nuevamente.

db.pets.find()

Resultado:

{ "_id" : 1, "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Horse" }
{ "_id" : 3, "name" : "Scratch", "type" : "Cat" }
{ "_id" : 4, "name" : "Fetch", "type" : "Dog" }

Entonces podemos ver que el nuevo documento fue alterado.

El parámetro arrayFilters

Cuando trabaje con arreglos, puede usar los arrayFilters parámetro junto con el posicional $ operador para determinar qué elementos de la matriz actualizar. Esto le permite actualizar un elemento de matriz en función de su valor, incluso si no conoce su posición.

Por ejemplo, supongamos que tenemos una colección llamada players con los siguientes documentos:

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 15, 11, 8 ] }

Podríamos ejecutar la siguiente consulta para actualizar solo aquellos elementos de la matriz que tengan un valor superior a cierta cantidad (en este caso, 10).

db.players.findAndModify({
   query: { scores: { $gte: 10 } },
   update: { $set: { "scores.$[e]" : 10 } },
   arrayFilters: [ { "e": { $gte: 10 } } ]
})

Resultado:

{ "_id" : 2, "scores" : [ 8, 17, 18 ] }

Como era de esperar, esto solo actualiza un documento, aunque dos documentos coinciden con los criterios.

Así es como se ven los documentos ahora.

db.players.find()

Resultado:

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 10, 10 ] }
{ "_id" : 3, "scores" : [ 15, 11, 8 ] }

El documento 2 tenía dos elementos de matriz actualizados, porque esos elementos coincidían con los criterios.

Más información

db.collection.findAndModify() El método también acepta otros parámetros, como writeConcern , collection , bypassDocumentValidation y más.

Consulte la documentación de MongoDB para db.collections.findAndModify() para más información.