sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB Upsert förklaras

Många uppdateringsoperationer i MongoDB har potential att bli upprörda. En upsert är en kombination av en insert och en uppdatering.

Det fungerar så här:Du utför en uppdateringsoperation baserat på filterkriterier, och om det finns några matchningar uppdateras bara de matchade dokumenten, men om det inte finns några matchningar infogas ett nytt dokument.

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 skulle kunna utföra följande uppdateringsoperation som ställer in upsert parameter till true :

db.pets.updateOne( 
    { name: "Wag" },
    { $set: { type: "Cow" } },
    { upsert: true }
    )

Resultat:

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 } 

I det här fallet fanns det ett matchande dokument (dvs. det finns ett dokument med name: "Wag" ) och därför uppdaterades det matchande dokumentet. Inget infogades.

Vi kan verifiera detta enligt följande:

db.pets.find()

Resultat:

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

Det första dokumentet har nu en type av Cow .

Låt oss köra ytterligare en uppdateringsoperation, igen med upsert: true . Men den här gången kommer det inte att finnas något matchande dokument att uppdatera.

db.pets.updateOne( 
    { name: "Bubbles" },
    { $set: { type: "Fish" } },
    { upsert: true }
    )

Resultat:

 {
 "acknowledged" : true,
 "matchedCount" : 0,
 "modifiedCount" : 0,
 "upsertedId" : ObjectId("5fe1b4c8d9914101694100b7")
 } 

I det här exemplet försöker vi hitta ett dokument som har name: "Bubbles" men det finns ingen att hitta.

Den här gången kan vi se att matchedCount är 0 och modifiedCount är också 0 . Det betyder att inga av de befintliga dokumenten uppdaterades.

Vi kan också se att ett upsertedId returnerades, vilket betyder att ett dokument har rubbats.

Låt oss ta en ny titt på samlingen av dokument:

db.pets.find()

Resultat:

 { "_id" : 1, "name" : "Wag", "type" : "Cow" }
 { "_id" : 2, "name" : "Bark", "type" : "Dog" }
 { "_id" : 3, "name" : "Meow", "type" : "Cat" }
 { "_id" : ObjectId("5fe1b4c8d9914101694100b7"), "name" : "Bubbles", "type" : "Fish" } 

Vi kan se att ett nytt dokument har infogats/upphävts och det har samma ID som anges ovan.

Upphävningen inträffade eftersom det den här gången inte fanns några matchande dokument att uppdatera (och så ett nytt infogades/uppsattes istället).

Om vi ​​inte hade ställt in upsert: true , det dokumentet skulle inte ha infogats.

Upsert på massuppdateringar

När du utför en massuppdatering, om du vill ange upsert: true , måste du använda den med Bulk.find.upsert() .

Detta kan användas med följande skrivoperationer:

  • Bulk.find.replaceOne()
  • Bulk.find.updateOne()
  • Bulk.find.update()

Syntaxen ser ut så här:

Bulk.find(<query>).upsert().update(<update>);
Bulk.find(<query>).upsert().updateOne(<update>);
Bulk.find(<query>).upsert().replaceOne(<replacement>);

Exempel:

var bulk = db.pets.initializeUnorderedBulkOp();
bulk.find( { name: "Bruce" } ).upsert().replaceOne(
   {
     name: "Bruce",
     type: "Bat",
   }
);
bulk.execute();

Resultat:

 BulkWriteResult({
 "writeErrors" : [ ],
 "writeConcernErrors" : [ ],
 "nInserted" : 0,
 "nUpserted" : 1,
 "nMatched" : 0,
 "nModified" : 0,
 "nRemoved" : 0,
 "upserted" : [
 {
 "index" : 0,
 "_id" : ObjectId("5fe1c179d9914101694100dd")
 }
 ]
 }) 

Vi kan se att ett dokument har rubbats. Vi kan också se _id som skapades för det dokumentet.

Nu när vi tittar på dokumenten i vår samling kan vi se det nya dokumentet som har rubbats:

db.pets.find()

Resultat:

 
 { "_id" : 1, "name" : "Wag", "type" : "Cow" }
 { "_id" : 2, "name" : "Bark", "type" : "Dog" }
 { "_id" : 3, "name" : "Meow", "type" : "Cat" }
 { "_id" : ObjectId("5fe1b4c8d9914101694100b7"), "name" : "Bubbles", "type" : "Fish" }
 { "_id" : ObjectId("5fe1c179d9914101694100dd"), "name" : "Bruce", "type" : "Bat" } 


  1. $nin med $expr

  2. distribuerar redis till heroku kan inte ansluta

  3. Mongoose - orsakad av ::11000 E11000 duplicate key error index?

  4. MongoDB $månad