In MongoDB de db.collection.findAndModify()
methode wijzigt en retourneert een enkel document.
De collection
deel is de naam van de verzameling waarmee de bewerking moet worden uitgevoerd.
Voorbeeld
Stel dat we een verzameling hebben met de naam pets
die de volgende documenten bevat:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
We kunnen de db.collection.findAndModify()
. gebruiken methode om een van die documenten te wijzigen.
db.pets.findAndModify({
query: { type: "Dog" },
update: { type: "Cow" }
})
Resultaat:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
Standaard wordt het originele document geretourneerd (niet de gewijzigde versie).
Merk op dat slechts één hond is bijgewerkt, ook al zijn er twee honden in de collectie.
Laten we de collectie eens bekijken.
db.pets.find()
Resultaat:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
We kunnen zien dat het eerste document nu een koe bevat in plaats van een hond. We kunnen echter ook zien dat het naamveld van het document is verdwenen.
Dat komt omdat, wanneer u een document doorgeeft aan de update
argument, db.collection.findAndModify()
voert een vervanging uit.
Een update-operator gebruiken
Als we een veld willen bijwerken, maar de rest van het document intact willen laten, moeten we de relevante expressie(s) van de update-operator in ons document opnemen.
Laten we, met de verzameling in de huidige staat, nog een findAndModify()
. uitvoeren operatie tegen, maar deze keer gebruiken we de $set
update-operator om alleen het veld in te stellen dat we willen wijzigen.
db.pets.findAndModify({
query: { type: "Dog" },
update: { $set: { type: "Horse" } }
})
Resultaat:
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
Deze keer is de overgebleven hond geüpdatet.
Laten we de collectie eens bekijken.
db.pets.find()
Resultaat:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Deze keer werd het relevante veld bijgewerkt en bleef de rest van het document intact.
Retourneer het gewijzigde document
Standaard wordt het originele document geretourneerd wanneer u db.collection.findAndModify()
gebruikt .
Als u liever wilt dat het gewijzigde document wordt geretourneerd, gebruikt u de new
parameter.
Standaard is dit new: false
, wat ertoe leidt dat het originele document wordt geretourneerd. Maar specificeren new: true
resulteert in dat het gewijzigde document in plaats daarvan wordt geretourneerd.
Laten we nog een wijziging aanbrengen, maar deze keer gebruiken we new: true
.
db.pets.findAndModify({
query: { name: "Meow" },
update: { $set: { name: "Scratch" } },
new: true
})
Resultaat:
{ "_id" : 3, "name" : "Scratch", "type" : "Cat" }
Dus hernoemden we Meow
naar Scratch
en de output weerspiegelt onze veranderingen.
Upserts
U kunt upserts uitvoeren door upsert: true
op te geven .
Een upsert is een optie die u kunt gebruiken bij updatebewerkingen. Als het opgegeven document niet bestaat, wordt een nieuw ingevoegd. Als het doet bestaat, wordt het originele document bijgewerkt (en wordt er geen document ingevoegd).
Voorbeeld met upsert: false
Hier is een voorbeeld van een poging om een niet-bestaand document bij te werken wanneer upsert: false
.
db.pets.findAndModify({
query: { _id: 4 },
update: { _id: 4, name: "Fetch", type: "Dog" },
new: true
})
Resultaat:
null
Het document bestond niet in de collectie en dus findAndModify()
null
geretourneerd . Ook al hebben we upsert: false
niet gespecificeerd , we weten dat het onwaar was, want dat is de standaardwaarde (d.w.z. dat is de waarde die wordt gebruikt wanneer u geen upsert-optie opgeeft).
Als we nog een keer in de collectie kijken, kunnen we zien dat het document niet is geüpdatet.
db.pets.find()
Resultaat:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Scratch", "type" : "Cat" }
Voorbeeld met upsert: true
Hier is het weer, maar deze keer specificeren we upsert: true
.
db.pets.findAndModify({
query: { _id: 4 },
update: { _id: 4, name: "Fetch", type: "Dog" },
new: true,
upsert: true
})
Resultaat:
{ "_id" : 4, "name" : "Fetch", "type" : "Dog" }
Deze keer wordt een nieuw document upserted en zien we het upserted document als de output (omdat we new: true
hebben gespecificeerd ).
Laten we de collectie nog eens bekijken.
db.pets.find()
Resultaat:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Scratch", "type" : "Cat" } { "_id" : 4, "name" : "Fetch", "type" : "Dog" }
We kunnen dus zien dat het nieuwe document inderdaad is geüpdatet.
De arrayFilters-parameter
Als u met arrays werkt, kunt u de arrayFilters
. gebruiken parameter samen met de positionele $
operator om te bepalen welke array-elementen moeten worden bijgewerkt. Dit stelt je in staat om een array-element bij te werken op basis van zijn waarde, zelfs als je de positie niet weet.
Stel dat we bijvoorbeeld een verzameling hebben met de naam players
met de volgende documenten:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
We zouden de volgende query kunnen uitvoeren om alleen die array-elementen bij te werken die een waarde hebben die hoger is dan een bepaald aantal (in dit geval 10).
db.players.findAndModify({
query: { scores: { $gte: 10 } },
update: { $set: { "scores.$[e]" : 10 } },
arrayFilters: [ { "e": { $gte: 10 } } ]
})
Resultaat:
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
Zoals verwacht, werkt dit slechts één document bij, ook al voldoen twee documenten aan de criteria.
Zo zien de documenten er nu uit.
db.players.find()
Resultaat:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 10, 10 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
Document 2 had twee array-elementen bijgewerkt, omdat die elementen aan de criteria voldeden.
Meer informatie
De db.collection.findAndModify()
methode accepteert ook andere parameters, zoals writeConcern
, collation
, bypassDocumentValidation
en meer.
Zie de MongoDB-documentatie voor db.collections.findAndModify()
voor meer informatie.