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

Guide til Upsert i MongoDB

1. Oversigt

Upsert er en kombination af insert og update (inSERT + UPdate =upsert). Vi kan bruge upsert med forskellige opdateringsmetoder, dvs. opdatering , findAndModify og replaceOne .

Her i MongoDB, upsert indstillingen er en boolesk værdi. Antag, at værdien er sand og dokumenterne matcher det angivne forespørgselsfilter. I så fald vil den anvendte opdateringshandling opdatere dokumenterne. Hvis værdien er sand og ingen dokumenter matcher betingelsen, indsætter denne mulighed et nyt dokument i samlingen. Det nye dokument vil indeholde felterne baseret på filter og anvendte operationer.

I denne øvelse vil vi først se på upsert i MongoDB Shell-forespørgsel, og brug derefter Java-driverkoden.

2. Databaseinitialisering

Før vi går videre for at udføre upsert operationer, først skal vi oprette en ny database baeldung og en prøvesamling, køretøj :

db.vehicle.insertMany([
{
    "companyName":"Nissan", 
    "modelName":"GTR",
    "launchYear":2016,
    "type":"Sports",
    "registeredNo":"EPS 5561"
},
{ 
    "companyName":"BMW",
    "modelName":"X5",
    "launchYear":2020,
    "type":"SUV",
    "registeredNo":"LLS 6899"
},
{
    "companyName":"Honda",
    "modelName":"Gold Wing",
    "launchYear":2018,
    "type":"Bike",
    "registeredNo":"LKS 2477"
}]);

I tilfælde af vellykket indsættelse vil ovenstående kommando udskrive en JSON svarende til den, der er vist nedenfor:

{
    "acknowledged" : true, 
    "insertedIds" : [
        ObjectId("623c1db39d55d4e137e4781b"),
	ObjectId("623c1db39d55d4e137e4781c"),
	ObjectId("623c1db39d55d4e137e4781d")
    ]
}

Vi har tilføjet dummy-dataene til indsamlings-køretøjet .

3. Brug af opdateringen Metode

I dette afsnit lærer vi at bruge upsert mulighed med opdatering metode. Hovedformålet med upsert mulighed er at opdatere det eksisterende dokument baseret på det anvendte filter eller indsætte et nyt dokument, hvis filteret ikke matcher .

Som illustration vil vi bruge $setOnInsert operatør med upsert mulighed for at få en ekstra fordel ved at indsætte nye felter i dokumentet.

Lad os se en forespørgsel, hvor filterbetingelsen matcher samlingens eksisterende dokument:

db.vehicle.update(
{
    "modelName":"X5"
},
{
    "$set":{
        "companyName":"Hero Honda"
    }
},
{
    "upsert":true
});

Ovenstående forespørgsel vil returnere følgende dokument:

{ 
    "nMatched" : 1, 
    "nUpserted" : 0,
    "nModified" : 1 
}

Her vil vi se Java-driverkoden, der svarer til ovenstående mongo shell-forespørgsel:

UpdateOptions options = new UpdateOptions().upsert(true);
UpdateResult updateResult = collection.updateOne(Filters.eq("modelName", "X5"), 
  Updates.combine(Updates.set("companyName", "Hero Honda")), options);
System.out.println("updateResult:- " + updateResult);

I ovenstående forespørgsel, feltet modelName "X5" findes allerede i samlingen, så feltet virksomhedsnavn af dette dokument vil blive opdateret til "Hero Honda".

Lad os nu se et eksempel på upsert mulighed ved at bruge $setOnInsert operatør. Det vil kun være gældende i tilfælde af tilføjelse af et nyt dokument:

db.vehicle.update(
{
    "modelName":"GTPR"
},
{
    "$set":{
        "companyName":"Hero Honda"
    },
    "$setOnInsert":{
        "launchYear" : 2022,
	"type" : "Bike",
	"registeredNo" : "EPS 5562"
    },  
},
{
    "upsert":true
});

Ovenstående forespørgsel vil returnere følgende dokument:

{
    "nMatched" : 0,
    "nUpserted" : 1,
    "nModified" : 0,
    "_id" : ObjectId("623b378ed648af670fe50e7f")
}

Java-driverkoden for ovenstående opdateringsforespørgsel med $setOnInsert mulighed vil være:

UpdateResult updateSetOnInsertResult = collection.updateOne(Filters.eq("modelName", "GTPR"),
  Updates.combine(Updates.set("companyName", "Hero Honda"),
  Updates.setOnInsert("launchYear", 2022),
  Updates.setOnInsert("type", "Bike"),
  Updates.setOnInsert("registeredNo", "EPS 5562")), options);
System.out.println("updateSetOnInsertResult:- " + updateSetOnInsertResult);

Her, i ovenstående forespørgsel, filterbetingelsen for feltet modelName "GTPR" matcher ikke noget samlingsdokument, så vi tilføjer et nyt dokument til samlingen. Det vigtigste punkt at bemærke er, at $setOnInsert tilføjer alle felterne i det nye dokument.

4. Brug af findAndModify Metode

Vi kan også bruge upsert mulighed ved at bruge findAndModify metode. For denne metode er standardværdien for upsert indstillingen er falsk . Hvis vi indstiller upsert mulighed for at sand , vil den udføre præcis det samme som opdateringsmetoden.

Lad os se et brugstilfælde af findAndModify metode med upsert mulighed sand :

db.vehicle.findAndModify(
{
    query:{
        "modelName":"X7"
    },
    update: {
        "$set":{
            "companyName":"Hero Honda"
        }
    },
    "upsert":true,
    "new":true
});

I dette tilfælde vil ovenstående forespørgsel returnere det nyoprettede dokument. Lad os tjekke Java-driverkoden for ovenstående forespørgsel:

FindOneAndUpdateOptions upsertOptions = new FindOneAndUpdateOptions();
  upsertOptions.returnDocument(ReturnDocument.AFTER);
  upsertOptions.upsert(true);
Document resultDocument = collection.findOneAndUpdate(Filters.eq("modelName", "X7"),
  Updates.set("companyName", "Hero Honda"), upsertOptions);
System.out.println("resultDocument:- " + resultDocument);

Her oprettede vi først filterbetingelsen, og baseret på det, opdaterer vi enten det eksisterende dokument eller tilføjer et nyt dokument til køretøjet til samlingen .

5. Brug af replaceOne Metode

Lad os udføre upsert betjening ved hjælp af replaceOne metode. replaceOne metoden for MongoDB erstatter blot det enkelte dokument i samlingen, hvis betingelsen matcher.

Lad os først se på Mongo shell-forespørgslen for erstatningsmetoden:

db.vehicle.replaceOne(
{
    "modelName":"GTPR"
},
{
    "modelName" : "GTPR",
    "companyName" : "Hero Honda",
    "launchYear" : 2022,
    "type" : "Bike",
    "registeredNo" : "EPS 5562"
},
{
    "upsert":true
});

Ovenstående forespørgsel vil returnere følgende svar:

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

Lad os nu skrive ovenstående forespørgsel ved hjælp af Java-driverkoden:

Document replaceDocument = new Document();
replaceDocument.append("modelName", "GTPP")
  .append("companyName", "Hero Honda")
  .append("launchYear", 2022)
  .append("type", "Bike")
  .append("registeredNo", "EPS 5562");
UpdateResult updateReplaceResult = collection.replaceOne(Filters.eq("modelName", "GTPP"), replaceDocument, options);
System.out.println("updateReplaceResult:- " + updateReplaceResult);

Her, i dette tilfælde, skal vi først oprette et nyt dokument, som vi vil erstatte det eksisterende dokument med, og med upsert mulighed sand , erstatter vi kun dokumentet, hvis betingelsen bliver matchet.


  1. Brug af redis med node.js (express)

  2. MongoDB:Hvordan forespørger man efter poster, hvor feltet er null eller ikke angivet?

  3. DbRef med Mongoose - mongoose-dbref eller befolke?

  4. Kræver Redis Cache i .NET Core 3 brugen af ​​Stack Exchange-pakken?