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

MongoDB trova e modifica ()

In MongoDB il db.collection.findAndModify() il metodo modifica e restituisce un singolo documento.

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.findAndModify() metodo per modificare uno di quei documenti.

db.pets.findAndModify({
    query: { type: "Dog" },
    update: { 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, "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. Tuttavia, possiamo anche vedere che il campo del nome del documento è scomparso.

Questo perché, quando passi un documento all'update argomento, db.collection.findAndModify() esegue una sostituzione.

Utilizzo di un operatore di aggiornamento

Se volessimo aggiornare un campo, ma lasciare intatto il resto del documento, dovremmo includere le espressioni dell'operatore di aggiornamento pertinenti nel nostro documento.

Con la raccolta nel suo stato attuale, eseguiamo un altro findAndModify() operazione contro di essa, ma questa volta useremo il $set update operator per impostare solo il campo che vogliamo venga modificato.

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

Risultato:

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

Questa volta il cane rimanente è stato aggiornato.

Diamo un'occhiata alla collezione.

db.pets.find()

Risultato:

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

Questa volta il campo pertinente è stato aggiornato e il resto del documento è rimasto intatto.

Restituisci il documento modificato

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

Se preferisci che venga restituito il documento modificato, usa il new parametro.

Per impostazione predefinita, questo è new: false , che comporta la restituzione del documento originale. Ma specificando new: true comporta invece la restituzione del documento modificato.

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

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

Risultato:

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

Quindi abbiamo rinominato Meow a Scratch e l'output riflette le nostre modifiche.

Alzati

Puoi eseguire upsert specificando upsert: true .

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

Esempio usando upsert: false

Ecco un esempio di tentativo di aggiornare un documento inesistente quando upsert: false .

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

Risultato:

null

Il documento non esisteva nella raccolta e quindi findAndModify() 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.findAndModify({
    query: { _id: 4 },
    update: { _id: 4, name: "Fetch", type: "Dog" },
    new: true,
    upsert: true
})

Risultato:

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

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

Controlliamo di nuovo la collezione.

db.pets.find()

Risultato:

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

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

Il parametro arrayFilters

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.findAndModify({
   query: { scores: { $gte: 10 } },
   update: { $set: { "scores.$[e]" : 10 } },
   arrayFilters: [ { "e": { $gte: 10 } } ]
})

Risultato:

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

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.findAndModify() accetta anche altri parametri, come writeConcern , collation , bypassDocumentValidation e altro ancora.

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