Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

$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.

In this short tutorial, we’ll introduce how to perform $push and $set operations together in a single update query.

2. Database Initialization

Before we move forward to perform the multiple update operations, we first need to set up a database baeldung and sample collection marks:

use baeldung;
db.createCollection(marks);

Let’s insert a few documents into the collection marks using the insertMany method of the MongoDB:

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.

3. Understanding the Problem

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.

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.

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.

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.

4. Using the MongoDB Shell Query

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.

Let’s checkout the example containing both $push and $set operators together:

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.

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.

5. Java Driver Code

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.

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.

Let’s now look into the Java driver code:

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”.

6. Conclusion

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.

As always, the source code and code snippet of all the examples is available over on GitHub.

Course – LSD (cat=Persistence)

Get started with Spring Data JPA through the reference Learn Spring Data JPA course:

>> CHECK OUT THE COURSE
res – Persistence (eBook) (cat=Persistence)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.