MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

MongoDB findOneAndUpdate()

In MongoDB il db.collection.findOneAndUpdate() il metodo aggiorna un singolo documento in base al filter e sort criteri.

La collection part è il nome della raccolta con cui eseguire l'operazione.

Esempio

Supponiamo di avere una collezione chiamata pets che contiene i seguenti documenti:

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

Possiamo usare db.collection.findOneAndUpdate() metodo per aggiornare uno di quei documenti.

db.pets.findOneAndUpdate(
    { "type": "Dog" },
    { $set: { "type": "Cow" } }
)

Risultato:

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

Per impostazione predefinita, restituisce il documento originale (non la versione modificata).

Tieni presente che è stato aggiornato un solo cane, anche se nella raccolta sono presenti due cani.

Controlliamo la collezione.

db.pets.find()

Risultato:

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

Possiamo vedere che il primo documento ora contiene una mucca invece di un cane.

Restituisci il documento modificato

Per impostazione predefinita, il documento originale viene restituito quando utilizzi db.collection.findOneAndUpdate() .

Se preferisci invece che venga restituito il documento modificato, utilizza returnNewDocument parametro.

Facciamo un'altra modifica, ma questa volta useremo returnNewDocument: true .

db.pets.findOneAndUpdate(
    { "type": "Dog" },
    { $set: { "type": "Horse" } },
    { returnNewDocument: true }
)

Risultato:

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

Questa volta l'altro cane è stato aggiornato. In questo caso, l'abbiamo cambiato in un cavallo e possiamo vedere che il documento di restituzione riflette questo.

Alzati

Un upsert è un'opzione che puoi utilizzare nelle operazioni di aggiornamento. Se il documento specificato non esiste, ne viene inserito uno nuovo. Se fa esiste, quindi il documento originale viene aggiornato (e nessun documento viene inserito).

Puoi eseguire upsert specificando upsert: true .

Esempio usando upsert: false

Innanzitutto, ecco un esempio di tentativo di aggiornare un documento inesistente quando upsert: false .

db.pets.findOneAndUpdate(
    { "_id": 4 },
    { $set: { "name": "Barry", "type": "Badger" } },
    { 
        returnNewDocument: true 
    }
)

Risultato:

null

Il documento non esisteva nella raccolta e quindi findOneAndUpdate() restituito null . Anche se non abbiamo specificato upsert: false , sappiamo che era falso perché è il valore predefinito (ovvero è il valore utilizzato quando non specifichi un'opzione di inserimento).

Se diamo un'altra occhiata alla raccolta, possiamo vedere che il documento non è stato modificato.

db.pets.find()

Risultato:

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

Esempio usando upsert: true

Ora eccolo di nuovo, ma questa volta specifichiamo upsert: true .

db.pets.findOneAndUpdate(
    { "_id": 4 },
    { $set: { "name": "Barry", "type": "Badger" } },
    { 
        upsert: true,
        returnNewDocument: true 
    }
)

Risultato:

{ "_id" : 4, "name" : "Barry", "type" : "Badger" }

Questa volta viene aggiornato un nuovo documento e vediamo il documento aggiornato come output (perché abbiamo specificato returnNewDocument: true ).

Controlliamo di nuovo la collezione.

db.pets.find()

Risultato:

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

Quindi possiamo vedere che il nuovo documento è stato effettivamente capovolto.

Gli arrayFilters Parametro

Quando si lavora con gli array, è possibile utilizzare arrayFilters parametro insieme al $ posizionale per determinare quali elementi dell'array aggiornare. Ciò ti consente di aggiornare un elemento dell'array in base al suo valore, anche se non conosci la sua posizione.

Ad esempio, supponiamo di avere una raccolta chiamata players con i seguenti documenti:

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

Potremmo eseguire la seguente query per aggiornare solo quegli elementi dell'array che hanno un valore superiore a un determinato importo (in questo caso 10).

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

Risultato:

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

Questo mostra il documento prima che fosse aggiornato. Come previsto, questo aggiorna solo un documento, anche se due documenti corrispondono ai criteri.

Ecco come sono ora i documenti.

db.players.find()

Risultato:

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

Nel documento 2 sono stati aggiornati due elementi dell'array, poiché tali elementi corrispondevano ai criteri.

Maggiori informazioni

Il db.collection.findOneAndUpdate() il metodo accetta anche altri parametri, come projection (per specificare un sottoinsieme di campi da restituire), sort , maxTimeMS e collation .

Consulta la documentazione di MongoDB per db.collections.findOneAndUpdate() per ulteriori informazioni.