MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

MongoDB findAndModify()


No MongoDB o db.collection.findAndModify() O método modifica e retorna um único documento.

A collection parte é o nome da coleção com a qual executar a operação.

Exemplo


Suponha que tenhamos uma coleção chamada pets que contém os seguintes documentos:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }

Podemos usar o db.collection.findAndModify() método para modificar um desses documentos.
db.pets.findAndModify({
    query: { type: "Dog" },
    update: { type: "Cow" }
})

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

Por padrão, ele retorna o documento original (não a versão modificada).

Observe que apenas um cão foi atualizado, embora existam dois cães na coleção.

Vamos conferir a coleção.
db.pets.find()

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

Podemos ver que o primeiro documento agora contém uma vaca em vez de um cachorro. No entanto, também podemos ver que o campo de nome do documento desapareceu.

Isso porque, quando você passa um documento para o update argumento, db.collection.findAndModify() realiza uma substituição.

Usando um operador de atualização


Se quiséssemos atualizar um campo, mas deixar o resto do documento intacto, precisaríamos incluir a(s) expressão(ões) do operador de atualização relevante(s) em nosso documento.

Com a coleção em seu estado atual, vamos executar outro findAndModify() operação contra ele, mas desta vez usaremos o $set update para definir apenas o campo que queremos alterar.
db.pets.findAndModify({
    query: { type: "Dog" },
    update: { $set: { type: "Horse" } }
})

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

Desta vez, o cão restante foi atualizado.

Vamos dar uma olhada na coleção.
db.pets.find()

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

Desta vez, o campo relevante foi atualizado e o restante do documento permaneceu intacto.

Devolva o documento modificado


Por padrão, o documento original é retornado quando você usa db.collection.findAndModify() .

Se preferir que o documento modificado seja devolvido, use o new parâmetro.

Por padrão, isso é new: false , o que resulta na devolução do documento original. Mas especificando new: true resulta no retorno do documento modificado.

Vamos fazer outra modificação, mas desta vez usaremos new: true .
db.pets.findAndModify({
    query: { name: "Meow" },
    update: { $set: { name: "Scratch" } },
    new: true
})

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

Então, renomeamos Meow para Scratch e a saída reflete nossas mudanças.

Upserts


Você pode realizar upserts especificando upsert: true .

Um upsert é uma opção que você pode usar em operações de atualização. Se o documento especificado não existir, um novo será inserido. Se sim existir, o documento original será atualizado (e nenhum documento será inserido).

Exemplo usando upsert: false


Aqui está um exemplo de tentativa de atualizar um documento inexistente quando upsert: false .
db.pets.findAndModify({
    query: { _id: 4 },
    update: { _id: 4, name: "Fetch", type: "Dog" },
    new: true
})

Resultado:
null

O documento não existia na coleção e então findAndModify() retornou null . Embora não tenhamos especificado upsert: false , sabemos que era falso porque esse é o valor padrão (ou seja, esse é o valor usado quando você não especifica uma opção de upsert).

Se dermos outra olhada na coleção, podemos ver que o documento não foi upserted.
db.pets.find()

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

Exemplo usando upsert: true


Agora aqui está novamente, mas desta 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" }

Desta vez, um novo documento é upserted e vemos o documento upserted como a saída (porque especificamos new: true ).

Vamos verificar a coleção novamente.
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" }

Assim, podemos ver que o novo documento foi de fato alterado.

O parâmetro arrayFilters


Ao trabalhar com arrays, você pode usar os arrayFilters parâmetro junto com o posicional $ operador para determinar quais elementos da matriz devem ser atualizados. Isso permite que você atualize um elemento da matriz com base em seu valor, mesmo que você não saiba sua posição.

Por exemplo, suponha que temos uma coleção chamada players com os seguintes documentos:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 15, 11, 8 ] }

Poderíamos executar a seguinte consulta para atualizar apenas os elementos do array que possuem um valor maior que um determinado valor (neste 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 esperado, isso atualiza apenas um documento, mesmo que dois documentos correspondam aos critérios.

Veja como estão os documentos agora.
db.players.find()

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

O Documento 2 teve dois elementos do array atualizados, porque esses elementos correspondiam aos critérios.

Mais informações


O db.collection.findAndModify() também aceita outros parâmetros, como writeConcern , collection , bypassDocumentValidation e mais.

Consulte a documentação do MongoDB para db.collections.findAndModify() Para maiores informações.