1. Overview
1.概述
MongoDB is a cross-platform, document-oriented, open-source NoSQL database, written in C++. Additionally, MongoDB provides high performance, high availability, and automatic scaling.
MongoDB是一个跨平台、面向文档、开源的NoSQL数据库,由C++编写。此外,MongoDB还提供了高性能、高可用性和自动扩展功能。
In order to update the documents in MongoDB, we can use different methods like updateOne, findOneAndUpdate, etc. Furthermore, MongoDB provides various operators for the update methods.
为了更新MongoDB中的文档,我们可以使用不同的方法,比如updateOne,findOneAndUpdate,等。此外,MongoDB为更新方法提供了各种操作符。
In this tutorial, we’ll discuss different approaches to perform update operations in MongoDB. For each approach, we’ll first discuss the mongo shell query and then its implementation in Java.
在本教程中,我们将讨论在MongoDB中执行更新操作的不同方法。对于每种方法,我们将首先讨论mongo shell查询,然后用Java实现。
2. Database Setup
2.数据库设置
Before we move on to the update queries, let’s first create a database, baeldung, and a sample collection, student:
在我们进入更新查询之前,让我们首先创建一个数据库baeldung,和一个样本集合student:。
use baeldung;
db.createCollection(student);
As an illustration, let’s add a few documents into the collection student using the insertMany query:
作为说明,让我们使用insertMany查询将一些文档添加到集合student中。
db.student.insertMany([
{
"student_id": 8764,
"student_name": "Paul Starc",
"address": "Hostel 1",
"age": 16,
"roll_no":199406
},
{
"student_id": 8765,
"student_name": "Andrew Boult",
"address": "Hostel 2",
"age": 18,
"roll_no":199408
}
]);
On successful insertion, we’ll get a JSON with acknowledged:true:
插入成功后,我们将得到一个带有acknowledged:true的JSON。
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("621b078485e943405d04b557"),
ObjectId("621b078485e943405d04b558")
]
}
Let’s now dive deep into different ways to update the documents in MongoDB.
现在让我们深入了解在MongoDB中更新文档的不同方法。
3. Using the updateOne Method
3.使用updateOne方法
An update operation in MongoDB can be done by adding a new field, removing a field, or updating an existing field. The updateOne method updates a single document in a collection based on the applied query filter. It first finds the document that matches the filter and then updates the specified fields.
MongoDB中的更新操作可以通过添加一个新字段、删除一个字段或更新一个现有字段来完成。updateOne方法根据应用的查询过滤器更新集合中的单个文档。它首先找到符合过滤器的文档,然后更新指定的字段。
In addition, we can use different operators such as $set, $unset, $inc, etc., with the update method.
此外,我们可以使用不同的操作符,如$set、$unset、$inc,等等,与更新方法一起。
To demonstrate, let’s look into the query to update a single document of a collection:
为了证明这一点,我们来看看更新一个集合的单个文件的查询。
db.student.updateOne(
{
"student_name" : "Paul Starc"
},
{
$set: {
"address" : "Hostel 2"
}
}
);
We’ll get an output similar to the one shown below:
我们将得到一个类似于下图的输出。
{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}
Let’s now check out the Java driver code of the above updateOne query:
现在我们来看看上述updateOne查询的Java驱动代码。
UpdateResult updateResult = collection.updateOne(Filters.eq("student_name", "Paul Starc"),
Updates.set("address", "Hostel 2"));
Here, firstly we have used the student_name field to filter the documents. Then we update the address of the document with student_name “Paul Starc”.
在这里,首先我们使用了student_name字段来过滤文件。然后我们用student_name “Paul Starc “来更新文件的地址。
4. Using the updateMany Method
4.使用updateMany方法
The updateMany method updates all the documents in MongoDB collections that match the given filter. One of the benefits of using the updateMany is that we can update multiple documents without losing the fields of old documents.
updateMany方法更新MongoDB集合中符合给定过滤器的所有文档。使用updateMany的一个好处是,我们可以更新多个文档而不会丢失旧文档的字段。
Let’s see the MongoDB shell query using updateMany method:
让我们看看使用updateMany方法的MongoDB shell查询。
db.student.updateMany(
{
age: {
$lt: 20
}
},
{
$set:{
"Review" : true
}
}
);
The above command will return the following output:
上述命令将返回以下输出。
{
"acknowledged":true,
"matchedCount":2,
"modifiedCount":2
}
Here, matchedCount contains the number of matched documents, whereas modifiedCount contains the modified documents number.
这里,matchedCount包含匹配的文档数量,而modifiedCount包含修改的文档数量。
Let’s now look into the Java driver code using the updateMany method:
现在我们来看看使用updateMany方法的Java驱动代码。
UpdateResult updateResult = collection.updateMany(Filters.lt("age", 20), Updates.set("Review", true));
Here, all the documents with age less than 20 will be filtered, and the Review field will be set to true.
这里,所有年龄小于20岁的文件将被过滤,评论字段将被设置为真。
5. Using the replaceOne Method
5.使用replaceOne方法
The replaceOne method of MongoDB replaces the entire document. One of the drawbacks of the replaceOne is that all the older fields will be replaced by the new fields, and the older fields will also be lost:
MongoDB的replaceOne方法取代了整个文档。replaceOne的一个缺点是,所有旧的字段将被新的字段所取代,而旧的字段也将丢失:。
db.student.replaceOne(
{
"student_id": 8764
},
{
"student_id": 8764,
"student_name": "Paul Starc",
"address": "Hostel 2",
"age": 18,
"roll_no":199406
}
);
In this case, we’ll get the following output:
在这种情况下,我们会得到以下输出。
{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}
If no matches are found, the operation returns the matchedCount as 0:
如果没有找到匹配,操作将返回matchedCount为0。
{
"acknowledged":true,
"matchedCount":0,
"modifiedCount":0
}
Let’s write the corresponding Java driver code using the replaceOne method:
让我们使用replaceOne方法编写相应的Java驱动代码。
Document replaceDocument = new Document();
replaceDocument
.append("student_id", 8764)
.append("student_name", "Paul Starc")
.append("address", "Hostel 2")
.append("age",18)
.append("roll_no", 199406);
UpdateResult updateResult = collection.replaceOne(Filters.eq("student_id", 8764), replaceDocument);
In the above code, we’ve created a document by which the older document will be replaced. The document with student_id 8764 will be replaced with the newly created document.
在上面的代码中,我们已经创建了一个文档,旧的文档将被替换。带有student_id8764的文档将被新创建的文档所取代。
6. Using the findOneAndReplace Method
6.使用findOneAndReplace方法
The findOneAndReplace method is one of the advanced update methods provided by MongoDB, and it replaces the first matched document based on the given selection criteria. By default, this method returns the original document. We can use different options of the findOneAndReplace to sort and project documents if required.
findOneAndReplace方法是MongoDB提供的高级更新方法之一,它根据给定的选择条件,替换第一个匹配的文档。默认情况下,该方法返回原始文档。如果需要,我们可以使用findOneAndReplace的不同选项来对文档进行排序和项目。
In short, findOneAndReplace replaces the first matching document of the collection on the basis of the applied filter:
简而言之,findOneAndReplace在应用的过滤器的基础上替换集合中第一个匹配的文档。
db.student.findOneAndReplace(
{
"student_id" : {
$eq : 8764
}
},
{
"student_id" : 8764,
"student_name" : "Paul Starc",
"address": "Hostel 2",
"age": 18,
"roll_no":199406
},
{
returnNewDocument: false
}
);
This query will return the following document:
该查询将返回以下文件。
{
"student_id":8764,
"student_name":"Paul Starc",
"address":"Hostel 1",
"age":16,
"roll_no":199406
}
If we set returnNewDocument to true, the operation would then return the replaced document instead:
如果我们将returnNewDocument设置为true,那么该操作将返回被替换的文档。
{
"student_id":8764,
"student_name":"Paul Starc",
"address":"Hostel 2",
"age":18,
"roll_no":199406
}
Let’s now use the findOneAndReplace method to project the student_id and age fields in the returned document:
现在让我们使用findOneAndReplace方法来投射返回文档中的student_id和age字段。
db.student.findOneAndReplace(
{
"student_id" : {
$eq : 8764
}
},
{
"student_id" : 8764,
"student_name" : "Paul Starc",
"address": "Hostel 2",
"age": 18,
"roll_no":199406
},
{
projection: {
"_id" : 0,
"student_id":1,
"age" : 1
}
}
);
The output of the above query will only contain the projected fields:
上述查询的输出将只包含预测字段。
{
"student_id":"8764",
"age":16
}
The Java driver code of the above query with various options of the findOneAndReplace:
上述查询的Java驱动代码,包含findOneAndReplace的各种选项:。
Document replaceDocument = new Document();
replaceDocument
.append("student_id", 8764)
.append("student_name", "Paul Starc")
.append("address", "Hostel 2")
.append("age", 18)
.append("roll_no", 199406);
Document sort = new Document("roll_no", 1);
Document projection = new Document("_id", 0).append("student_id", 1).append("address", 1);
Document resultDocument = collection.findOneAndReplace(
Filters.eq("student_id", 8764),
replaceDocument,
new FindOneAndReplaceOptions().upsert(true).sort(sort).projection(projection).returnDocument(ReturnDocument.AFTER));
In the above query, the findOneAndReplace method will first sort the documents in ascending order based on roll_no, and the newly created document replaces the document with student_id “8764”.
在上面的查询中,findOneAndReplace方法将首先根据roll_no对文件进行升序排序,而新创建的文件将取代student_id“8764 “的文件。
7. Using the findOneAndUpdate Method
7.使用findOneAndUpdate方法
The findOneAndUpdate method updates the first matched document in the collection. If more than one document matches the selection criteria, then it updates only the first matched document. When we update the document, the value of the _id field remains unchanged:
findOneAndUpdate方法更新集合中第一个匹配的文档。如果有一个以上的文档符合选择标准,那么它只更新第一个匹配的文档。当我们更新文档时,_id字段的值保持不变。
db.student.findOneAndUpdate(
{
"student_id" : 8764
},
{
$inc : {
"roll_no" : 5
}
},
{
sort: {
"roll_no" : 1
},
projection: {
"_id" : 0,
"student_id":1,
"address" : 1
}
}
);
The output of the query will only contain the studentId and address of the older document:
查询的输出将只包含旧文件的studentId和address。
{
"student_id":8764,
"address":"Hostel 1"
}
The Java driver code of the above query, using different options of the findOneAndUpdate is as follows:
上述查询的Java驱动代码,使用findOneAndUpdate的不同选项,如下所示:。
Document sort = new Document("roll_no", 1);
Document projection = new Document("_id", 0).append("student_id", 1).append("address", 1);
Document resultDocument = collection.findOneAndUpdate(
Filters.eq("student_id", 8764),
Updates.inc("roll_no", 5),
new FindOneAndUpdateOptions().sort(sort).projection(projection).returnDocument(ReturnDocument.BEFORE));
In this case, the findOneAndUpdate method will first sort the document in ascending order based on roll_no. The above query increments the roll_no by 5 and then returns the student_id and address fields.
在这种情况下,findOneAndUpdate方法将首先根据roll_no以升序对文件进行排序。上面的查询将roll_no增加5,然后返回student_id和address字段。
8. Conclusion
8.结语
In this article, we’ve seen various ways to update the documents in MongoDB. First, we looked into the MongoDB shell query, and then we discussed the corresponding Java driver code.
在这篇文章中,我们已经看到了更新MongoDB中文档的各种方法。首先,我们研究了MongoDB的shell查询,然后我们讨论了相应的Java驱动代码。
The implementation of all these examples and code snippets can be found over on GitHub.
所有这些例子和代码片断的实现都可以在GitHub上找到over。