1. Overview
1.概述
$push is an update operator in MongoDB that adds the value in an array. In contrast, the $set operator is used to update the value of an existing field in the document.
$push是MongoDB中的一个更新操作符,用于添加数组中的值。相比之下,$set操作符则用于更新文档中现有字段的值。
In this short tutorial, we’ll introduce how to perform $push and $set operations together in a single update query.
在这个简短的教程中,我们将介绍如何在一个更新查询中一起执行$push和$set操作。
2. Database Initialization
2.数据库初始化
Before we move forward to perform the multiple update operations, we first need to set up a database baeldung and sample collection marks:
在我们继续执行多重更新操作之前,我们首先需要设置一个数据库baeldung和样本集marks。
use baeldung;
db.createCollection(marks);
Let’s insert a few documents into the collection marks using the insertMany method of the MongoDB:
让我们使用MongoDB的insertMany方法向集合marks中插入一些文档。
db.marks.insertMany([
{
"studentId": 1023,
"studentName":"James Broad",
"joiningYear":"2018",
"totalMarks":100,
"subjectDetails":[
{
"subjectId":123,
"subjectName":"Operating Systems Concepts",
"marks":40
},
{
"subjectId":124,
"subjectName":"Numerical Analysis",
"marks":60
}
]
},
{
"studentId": 1024,
"studentName":"Chris Overton",
"joiningYear":"2018",
"totalMarks":110,
"subjectDetails":[
{
"subjectId":123,
"subjectName":"Operating Systems Concepts",
"marks":50
},
{
"subjectId":124,
"subjectName":"Numerical Analysis",
"marks":60
}
]
}
]);
On successful insertion, the above query will return the following response:
插入成功后,上述查询将返回以下响应。
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("622300cc85e943405d04b567"),
ObjectId("622300cc85e943405d04b568")
]
}
So far, we have successfully inserted a few sample documents into the collection marks.
到目前为止,我们已经成功地将一些样本文件插入到集合marks。
3. Understanding the Problem
3.了解问题
In order to understand the problem, let’s first understand the document that we just inserted. It includes the student details and the marks obtained by them in different subjects. The totalMarks is the sum of marks that are obtained in different subjects.
为了理解这个问题,让我们首先了解一下我们刚刚插入的文件。它包括学生的详细资料和他们在不同科目中获得的分数。totalMarks是在不同科目中获得的分数之和。
Let’s consider a situation where we wish to add a new subject in the subjectDetails array. To also make the data consistent, we need to update the totalMarks field as well.
让我们考虑一种情况,我们希望在subjectDetails数组中添加一个新的主题。为了使数据一致,我们也需要更新totalMarks字段。
In MongoDB, first, we’ll add the new subject into the array using the $push operator. Then we’ll set the totalMarks field to a particular value using the $set operator.
在MongoDB中,首先,我们将使用$push操作符将新主题添加到数组中。然后,我们将使用$set操作符将totalMarks字段设置为一个特定值。
Both these operations can be performed individually using the $push and $set operator, respectively. But we can write the MongoDB query to perform both the operations together.
这两种操作都可以分别使用$push和$set操作符单独执行。但是我们可以编写MongoDB查询来同时执行这两项操作。
4. Using the MongoDB Shell Query
4.使用MongoDB外壳查询
In MongoDB, we can update multiple fields of a document using the different update operators. Here, we will use both $push and $set operators together in a updateOne query.
在MongoDB中,我们可以使用不同的更新操作符来更新一个文档的多个字段。在这里,我们将在一个$push和$set操作符中同时使用updateOne查询。
Let’s checkout the example containing both $push and $set operators together:
让我们看看同时包含$push和$set操作符的例子。
db.marks.updateOne(
{
"studentId": 1023
},
{
$set: {
totalMarks: 170
},
$push: {
"subjectDetails":{
"subjectId": 126,
"subjectName": "Java Programming",
"marks": 70
}
}
}
);
Here, in the above query, we’ve added the filter query based on the studentId. Once we get the filtered document, we then update the totalMarks using the $set operator. In addition to that, we insert the new subject data into the subjectDetails array using the $push operator.
在这里,在上面的查询中,我们已经添加了基于studentId的过滤查询。一旦我们得到过滤后的文件,我们就使用$set操作符更新totalMarks。除此之外,我们使用$push操作符将新的主题数据插入subjectDetails数组中。
As a result, the above query will return the following output:
因此,上述查询将返回以下输出。
{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}
Here, the matchedCount contains the document count that matched the filter, whereas the modifiedCount contains the number of modified documents.
这里,matchedCount包含匹配过滤器的文件数,而modifiedCount包含修改的文件数。
5. Java Driver Code
5.Java驱动代码
So far, we discussed the mongo shell query to use the $push and $set operator together. Here, we’ll learn to implement the same using the Java driver code.
到目前为止,我们讨论了在mongo shell查询中一起使用$push和$set操作符。在这里,我们将学习使用Java驱动代码来实现同样的内容。
Before we move forward, let’s first connect to the DB and the required collection:
在我们继续前进之前,首先让我们连接到数据库和所需的集合。
MongoClient mongoClient = new MongoClient(new MongoClientURI("localhost", 27017);
MongoDatabase database = mongoClient.getDatabase("baeldung");
MongoCollection<Document> collection = database.getCollection("marks");
Here, we are connecting to MongoDB, which is running at port default port 27017 on localhost.
在这里,我们要连接到MongoDB,它运行在localhost的默认端口27017。
Let’s now look into the Java driver code:
现在让我们来看看Java驱动的代码。
Document subjectData = new Document()
.append("subjectId", 126)
.append("subjectName", "Java Programming")
.append("marks", 70);
UpdateResult updateQueryResult = collection.updateOne(Filters.eq("studentId", 1023),
Updates.combine(Updates.set("totalMarks", 170),
Updates.push("subjectDetails", subjectData)));
In this code snippet, we’ve used the updateOne method, which updates only a single document based on the applied filter studentId 1023. We then used the Updates.combine to perform multiple operations in a single call. The field totalMarks will be updated to 170, and a new document subjectData will be pushed to the array field “subjectDetails”.
在这个代码片段中,我们使用了updateOne方法,该方法只根据应用的过滤器studentId1023更新一个文档。然后我们使用Updates.combined来在一次调用中执行多个操作。字段totalMarks将被更新为170,并且一个新的文档subjectData将被推送到数组字段“subjectDetails”。
6. Conclusion
6.结论
In this article, we understood the use case of applying multiple operations together in a single MongoDB query. Further, we executed the same using the MongoDB shell query and Java driver code.
在这篇文章中,我们了解了在单个MongoDB查询中一起应用多种操作的用例。此外,我们使用MongoDB shell查询和Java驱动代码执行了同样的操作。
As always, the source code and code snippet of all the examples is available over on GitHub.
一如既往,所有例子的源代码和代码片段都可以在GitHub上找到。