sql >> Database >  >> NoSQL >> MongoDB

MongoDB findAndModify()

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.


  1. Mongodb:$in-operator versus veel enkele zoekopdrachten

  2. Redis actief-actieve replicatie

  3. Aan de slag met niet-relationele databases met Mongodb

  4. MongoRegex gebruiken (MongoDB C#-stuurprogramma)