sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB findOneAndUpdate()

I MongoDB används db.collection.findOneAndUpdate() metod uppdaterar ett enda dokument baserat på filter och sort kriterier.

collection del är namnet på samlingen med vilken operationen ska utföras.

Exempel

Anta att vi har en samling som heter pets som innehåller följande dokument:

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

Vi kan använda db.collection.findOneAndUpdate() metod för att uppdatera ett av dessa dokument.

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

Resultat:

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

Som standard returnerar den originaldokumentet (inte den modifierade versionen).

Observera att endast en hund uppdaterades, även om det finns två hundar i samlingen.

Låt oss kolla in samlingen.

db.pets.find()

Resultat:

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

Vi kan se att det första dokumentet nu innehåller en ko istället för en hund.

Returnera det ändrade dokumentet

Som standard returneras originaldokumentet när du använder db.collection.findOneAndUpdate() .

Om du föredrar att få det ändrade dokumentet returnerat istället, använd returnNewDocument parameter.

Låt oss göra en annan ändring, men den här gången använder vi returnNewDocument: true .

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

Resultat:

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

Den här gången uppdaterades den andra hunden. I det här fallet ändrade vi det till en häst, och vi kan se att returdokumentet speglar detta.

Uppserts

En upsert är ett alternativ som du kan använda vid uppdateringsoperationer. Om det angivna dokumentet inte finns infogas ett nytt. Om den gör det existerar, då uppdateras originaldokumentet (och inget dokument infogas).

Du kan utföra upserts genom att ange upsert: true .

Exempel med upsert: false

Först, här är ett exempel på att försöka uppdatera ett icke-existerande dokument när upsert: false .

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

Resultat:

null

Dokumentet fanns inte i samlingen och därför findOneAndUpdate() returnerade null . Även om vi inte angav upsert: false , vi vet att det var falskt eftersom det är standardvärdet (dvs det är det värde som används när du inte anger ett upphävandealternativ).

Om vi ​​tittar igen i samlingen kan vi se att dokumentet inte har rubbats.

db.pets.find()

Resultat:

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

Exempel med upsert: true

Nu är den här igen, men den här gången anger vi upsert: true .

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

Resultat:

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

Den här gången läggs ett nytt dokument upp och vi ser det upphävda dokumentet som utdata (eftersom vi angav returnNewDocument: true ).

Låt oss kolla in samlingen igen.

db.pets.find()

Resultat:

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

Så vi kan se att det nya dokumentet faktiskt var upphävt.

arrayFilters Parameter

När du arbetar med arrayer kan du använda arrayFilters parametern tillsammans med den positionella $ operatör för att bestämma vilka arrayelement som ska uppdateras. Detta gör att du kan uppdatera ett matriselement baserat på dess värde, även om du inte vet dess position.

Anta till exempel att vi har en samling som heter players med följande dokument:

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

Vi skulle kunna köra följande fråga för att bara uppdatera de arrayelement som har ett värde som är högre än ett visst belopp (i det här fallet 10).

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

Resultat:

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

Detta visar dokumentet innan det uppdaterades. Som väntat uppdaterar detta bara ett dokument, även om två dokument matchar kriterierna.

Så här ser dokumenten ut nu.

db.players.find()

Resultat:

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

Dokument 2 hade två arrayelement uppdaterade, eftersom dessa element matchade kriterierna.

Mer information

db.collection.findOneAndUpdate() Metoden accepterar även andra parametrar, såsom projection (för att ange en delmängd av fält att returnera), sort , maxTimeMS och collation .

Se MongoDB-dokumentationen för db.collections.findOneAndUpdate() för mer information.


  1. Få MongoDB på Linux att lyssna på fjärranslutningar

  2. Det gick inte att starta MongoDB. FEL:Adr används redan

  3. Kan strikta JSON $datum användas i en MongoDB-fråga?

  4. Hur använder du $set i MongoDB för att uppdatera ett kapslat värde/inbäddat dokument?