1. Overview
1.概述
Upsert is a combination of insert and update (inSERT + UPdate = upsert). We can use the upsert with different update methods, i.e., update, findAndModify, and replaceOne.
Upsert是插入和更新的组合(inSERT + UPdate = upsert)。我们可以使用upsert与不同的更新方法,即update,findAndModify,和replaceOne。
Here in MongoDB, the upsert option is a Boolean value. Suppose the value is true and the documents match the specified query filter. In that case, the applied update operation will update the documents. If the value is true and no documents match the condition, this option inserts a new document into the collection. The new document will contain the fields based on filter and applied operations.
在MongoDB中,upsert选项是一个Boolean值。假设该值为true,并且文档符合指定的查询过滤器。在这种情况下,应用的更新操作将更新这些文档。如果值是true,并且没有符合条件的文档,这个选项将在集合中插入一个新的文档。这个新的文档将包含基于过滤器和应用操作的字段。
In this tutorial, we’ll first look at the upsert in MongoDB Shell query and then use the Java driver code.
在本教程中,我们将首先了解MongoDB Shell查询中的upsert,然后使用Java驱动代码。
2. Database Initialization
2.数据库初始化
Before we move forward to perform the upsert operations, first we need to set up a new database baeldung and a sample collection, vehicle:
在我们继续执行upsert操作之前,首先我们需要建立一个新的数据库baeldung和一个样本集合,vehicle。
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"
}]);
In case of successful insertion, the above command will print a JSON similar to the one shown below:
在插入成功的情况下,上述命令将打印一个类似于下图的JSON。
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("623c1db39d55d4e137e4781b"),
ObjectId("623c1db39d55d4e137e4781c"),
ObjectId("623c1db39d55d4e137e4781d")
]
}
We have successfully added the dummy data into the collection vehicle.
我们已经成功地将假数据添加到集合vehicle。
3. Using the update Method
3.使用update方法
In this section, we’ll learn to use the upsert option with the update method. The main purpose of the upsert option is to update the existing document based on the applied filter or insert a new document if the filter doesn’t get the match.
在本节中,我们将学习如何使用upsert选项和update方法。upsert选项的主要目的是根据应用的过滤器来更新现有的文档,或者在过滤器没有得到匹配的情况下插入一个新的文档。
As an illustration, we will use the $setOnInsert operator with the upsert option to get an additional advantage on inserting new fields into the document.
作为一个例子,我们将使用$setOnInsert操作符和upsert选项来获得在文档中插入新字段的额外优势。
Let’s check out a query in which the filter condition matches the existing document of the collection:
让我们来看看一个查询,其中的过滤条件与集合的现有文件相匹配。
db.vehicle.update(
{
"modelName":"X5"
},
{
"$set":{
"companyName":"Hero Honda"
}
},
{
"upsert":true
});
The above query will return the following document:
上述查询将返回以下文件。
{
"nMatched" : 1,
"nUpserted" : 0,
"nModified" : 1
}
Here, we’ll see the Java driver code corresponding to the above mongo shell query:
在这里,我们将看到对应于上述mongo shell查询的Java驱动代码。
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);
In the above query, the field modelName “X5” already exists in the collection, so the field companyName of that document will be updated to “Hero Honda”.
在上述查询中,字段modelName“X5 “已经存在于集合中,所以该文件的字段companyName将被更新为 “Hero Honda”。
Now let’s check out an example of upsert option using the $setOnInsert operator. It will be applicable only in the case of adding a new document:
现在让我们看看一个使用$setOnInsert操作符的upsert选项的例子。它只适用于添加一个新文件的情况。
db.vehicle.update(
{
"modelName":"GTPR"
},
{
"$set":{
"companyName":"Hero Honda"
},
"$setOnInsert":{
"launchYear" : 2022,
"type" : "Bike",
"registeredNo" : "EPS 5562"
},
},
{
"upsert":true
});
The above query will return the following document:
上述查询将返回以下文件。
{
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("623b378ed648af670fe50e7f")
}
The Java driver code of the above update query with the $setOnInsert option will be:
上述带有$setOnInsert选项的更新查询的Java驱动代码将是。
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);
Here, in the above query, the filter condition of field modelName “GTPR” doesn’t match any collection document, so we’ll add a new document to the collection. The key point to note is that the $setOnInsert adds all the fields into the new document.
在这里,在上面的查询中,字段modelName“GTPR “的过滤条件不匹配任何集合文档,所以我们将向集合添加一个新文档。需要注意的关键点是,$setOnInsert将所有字段添加到新文档中。
4. Using the findAndModify Method
4.使用findAndModify方法
We can also use the upsert option using the findAndModify method. For this method, the default value of the upsert option is false. If we set the upsert option to true, it’ll perform precisely the same as the update method.
我们也可以使用upsert选项,使用findAndModify方法。对于这个方法,upsert选项的默认值是false。如果我们将upsert选项设置为true,它的执行情况将与更新方法完全相同。
Let’s check out a use case of the findAndModify method with the upsert option true:
让我们来看看findAndModify方法的一个用例,upsert选项true。
db.vehicle.findAndModify(
{
query:{
"modelName":"X7"
},
update: {
"$set":{
"companyName":"Hero Honda"
}
},
"upsert":true,
"new":true
});
In this case, the above query will return the newly created document. Let’s check out the Java driver code of the above query:
在这种情况下,上述查询将返回新创建的文档。让我们来看看上述查询的Java驱动代码。
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);
Here, we first created the filter condition and based on that, either we’ll update the existing document or add a new document to the collection vehicle.
在这里,我们首先创建了过滤条件,在此基础上,我们将更新现有的文档或添加一个新的文档到集合vehicle。
5. Using the replaceOne Method
5.使用replaceOne方法
Let’s perform the upsert operation using the replaceOne method. The replaceOne method of MongoDB just replaces the single document within the collection if the condition matches.
让我们使用replaceOne方法来执行upsert操作。MongoDB的replaceOne方法只是在条件匹配的情况下替换集合中的单个文档。
First, let’s look into the Mongo shell query of the replace method:
首先,让我们研究一下替换方法的Mongo shell查询。
db.vehicle.replaceOne(
{
"modelName":"GTPR"
},
{
"modelName" : "GTPR",
"companyName" : "Hero Honda",
"launchYear" : 2022,
"type" : "Bike",
"registeredNo" : "EPS 5562"
},
{
"upsert":true
});
The above query will return the following response:
上述查询将返回以下响应。
{
"acknowledged" : true,
"matchedCount" : 1,
"modifiedCount" : 1
}
Now, let’s write the above query using the Java driver code:
现在,让我们用Java驱动代码编写上述查询。
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);
Here, in this case, we need first to create a new document by which we want to replace the existing document, and with the upsert option true, we’ll replace the document only if the condition gets matched.
在这里,在这种情况下,我们首先需要创建一个新的文档,通过它来替换现有的文档,并且通过upsert选项true,我们将只在条件被匹配时替换文档。
6. Conclusion
6.结语
In this article, we’ve seen how to perform upsert operation with various update methods of MongoDB. First, we learned to execute the upsert with an update and findAndModify method and then use the replaceOne method. In short, we implemented the upsert operation using Mongo shell query and Java driver code.
在本文中,我们看到了如何使用MongoDB的各种更新方法执行upsert操作。首先,我们学会了用update和findAndModify方法来执行upsert,然后使用replaceOne方法。简而言之,我们使用Mongo shell查询和Java驱动代码实现了upsert操作。
The implementation of all the cases can be found over on GitHub.
所有案例的实现都可以在GitHub上找到over。