1. Översikt
Upsert är en kombination av infoga och uppdatera (inSERT + UPdate =upsert). Vi kan använda upsert med olika uppdateringsmetoder, t.ex. uppdatering , findAndModify och replaceOne .
Här i MongoDB, upsert alternativet är booleskt värde. Anta att värdet är true och dokumenten matchar det angivna frågefiltret. I så fall kommer den tillämpade uppdateringen att uppdatera dokumenten. Om värdet är true och inga dokument matchar villkoret, detta alternativ infogar ett nytt dokument i samlingen. Det nya dokumentet kommer att innehålla fälten baserade på filter och tillämpade operationer.
I den här självstudien kommer vi först att titta på upsert i MongoDB Shell-frågan och använd sedan Java-drivrutinskoden.
2. Databasinitiering
Innan vi går vidare för att utföra upsert operationer måste vi först skapa en ny databas baeldung och en provsamling, fordon :
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 händelse av lyckad infogning kommer kommandot ovan att skriva ut en JSON liknande den som visas nedan:
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("623c1db39d55d4e137e4781b"),
ObjectId("623c1db39d55d4e137e4781c"),
ObjectId("623c1db39d55d4e137e4781d")
]
}
Vi har framgångsrikt lagt till dummydata i insamlingsfordonet .
3. Använda uppdateringen Metod
I det här avsnittet lär vi oss att använda upsert alternativet med uppdatering metod. Huvudsyftet med upsert alternativet är att uppdatera det befintliga dokumentet baserat på det tillämpade filtret eller infoga ett nytt dokument om filtret inte får matchningen .
Som en illustration kommer vi att använda $setOnInsert operatören med upsert alternativet för att få en ytterligare fördel genom att infoga nya fält i dokumentet.
Låt oss kolla in en fråga där filtervillkoret matchar det befintliga dokumentet i samlingen:
db.vehicle.update(
{
"modelName":"X5"
},
{
"$set":{
"companyName":"Hero Honda"
}
},
{
"upsert":true
});
Ovanstående fråga returnerar följande dokument:
{
"nMatched" : 1,
"nUpserted" : 0,
"nModified" : 1
}
Här kommer vi att se Java-drivrutinskoden som motsvarar mongo-skalfrågan ovan:
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 ovanstående fråga, fältet modellnamn "X5" finns redan i samlingen, så fältet företagsnamn av det dokumentet kommer att uppdateras till "Hero Honda".
Låt oss nu kolla in ett exempel på upsert alternativet med $setOnInsert operatör. Det kommer endast att vara tillämpligt om du lägger till ett nytt dokument:
db.vehicle.update(
{
"modelName":"GTPR"
},
{
"$set":{
"companyName":"Hero Honda"
},
"$setOnInsert":{
"launchYear" : 2022,
"type" : "Bike",
"registeredNo" : "EPS 5562"
},
},
{
"upsert":true
});
Ovanstående fråga returnerar följande dokument:
{
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("623b378ed648af670fe50e7f")
}
Java-drivrutinskoden för ovanstående uppdateringsfråga med $setOnInsert alternativet kommer att vara:
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);
Här, i ovanstående fråga, filtervillkoret för fältet modellnamn "GTPR" matchar inte något insamlingsdokument, så vi lägger till ett nytt dokument i samlingen. Det viktigaste att notera är att $setOnInsert lägger till alla fält i det nya dokumentet.
4. Använda findAndModify Metod
Vi kan också använda upsert med hjälp av findAndModify metod. För den här metoden är standardvärdet för upsert alternativet är falskt . Om vi ställer in upsert alternativet till true , kommer den att utföra exakt samma som uppdateringsmetoden.
Låt oss kolla in ett användningsfall för findAndModify metod med upsert alternativet true :
db.vehicle.findAndModify(
{
query:{
"modelName":"X7"
},
update: {
"$set":{
"companyName":"Hero Honda"
}
},
"upsert":true,
"new":true
});
I det här fallet kommer ovanstående fråga att returnera det nyskapade dokumentet. Låt oss kolla in Java-drivrutinskoden för ovanstående fråga:
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);
Här skapade vi först filtervillkoret och baserat på det uppdaterar vi antingen det befintliga dokumentet eller lägger till ett nytt dokument till fordonet för samlingen .
5. Använda replaceOne Metod
Låt oss utföra upsert operation med replaceOne metod. replaceOne metoden för MongoDB ersätter bara det enskilda dokumentet i samlingen om villkoret matchar.
Låt oss först titta på Mongo-skalfrågan för ersätt-metoden:
db.vehicle.replaceOne(
{
"modelName":"GTPR"
},
{
"modelName" : "GTPR",
"companyName" : "Hero Honda",
"launchYear" : 2022,
"type" : "Bike",
"registeredNo" : "EPS 5562"
},
{
"upsert":true
});
Ovanstående fråga returnerar följande svar:
{
"acknowledged" : true,
"matchedCount" : 1,
"modifiedCount" : 1
}
Låt oss nu skriva ovanstående fråga med Java-drivrutinskoden:
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);
Här, i det här fallet, måste vi först skapa ett nytt dokument som vi vill ersätta det befintliga dokumentet med, och med upsert alternativ true , ersätter vi dokumentet endast om villkoret matchas.