MongoTemplate Spring Boot Example

MongoTemplate Spring Boot Example | MonogoTemplate is an auto-configured class given by Spring Data MongoDB, used to perform all operations over MongoDB Collection.

When we use MongoTemplate(C), no need to use the MongoRepository interface. We can directly use MongoTemplate(C) [Autowired] inside our application.

Query-based Operations:- We can define Query with Criteria which is also called as WHERE condition to execute FETCH/UPDATE/DELETE operations.

Criteria provide methods for all operations:- lt, ge, and, or, not, is, ….etc.

  • find(q, class): used to fetch matching data.
  • findAndModify(q, updateObject, class): Used to modify given updates.
  • findAndRemove(q, class): used to delete selected data.

Example:-

q.addCriteria(
    Criteria.where("stdName").is("C")
        .and("stdFee").gt(50.0)
        .and("stdName").ne(null)
);

Create a spring starter project and add the following dependencies:- Lombok, Spring Data MongoDB.

In application.properties:-

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=resttemplate
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document
public class Student {

    @Id
    private Integer stdId;
    private String stdName;
    private Double stdFee;
}
package com.knowprogram.demo.runner;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import com.knowprogram.demo.model.Student;

@Component
public class TestTemplateRunner implements CommandLineRunner {

    @Autowired
    private MongoTemplate mt;

    @Override
    public void run(String... args) throws Exception {

        // 1. save (insert/update)
        mt.save(new Student(10, "A", 3.3));
        mt.save(new Student(11, "B", 2.3));
        mt.save(new Student(12, "C", 4.3));

        // fetch data
        List<Student> list = mt.findAll(Student.class);
        list.forEach(System.out::println);

        // 3. condition based (Query) update/fetch/delete
        Query query = new Query();
        // where stdName = 'C' and stdFee != 5.5
        query.addCriteria(Criteria.where("stdName").is("C").and("stdFee").ne(5.5));

        // 3.a) fetch data
        mt.find(query, Student.class).forEach(System.out::println);

        // 3.b) update data
        Update update = new Update();
        update.set("stdName", "CAM");
        update.set("stdFee", 9.9);
        mt.findAndModify(query, update, Student.class);

        // 3.c) remove data
        mt.findAndRemove(query, Student.class);
    }
}

AND Operation

Query query = new Query();

// Add criteria to the query
query.addCriteria(Criteria.where("stdName").is("A"));
// By default it is AND
query.addCriteria(Criteria.where("stdFee").gte(3.3));

// Execute the query and retrieve the results
List<Student> list = mt.find(query, Student.class);

// Print the results
System.out.println(list);

OR Operation

Query query = new Query();
Criteria criteria = new Criteria();
query.addCriteria(criteria.orOperator(
    Criteria.where("stdName").is("A"),
    Criteria.where("stdFee").lte(2.3)
));
List<Student> list = mt.find(query, Student.class);
System.out.println(list);

The same can be written as:-

Query query = new Query();
query.addCriteria(Criteria.where("stdName").is("A")
    .orOperator(Criteria.where("stdFee").lte(2.3)));
List<Student> list = mt.find(query, Student.class);
System.out.println(list);

IN Operator

Query query = new Query();
query.addCriteria(Criteria.where("stdName").in(List.of("A", "B")));
List<Student> list = mt.find(query, Student.class);
System.out.println(list);

Not IN

query.addCriteria(Criteria.where("stdName").nin(List.of("A", "B")));

Check for exist, not null, and not empty:-

query.addCriteria(Criteria.where("stdName")
    .exists(true)  // Ensures the field exists
    .ne(null)   // Ensures the field is not null
    .ne("")     // Ensures the field is not an empty string
);

It can also have regex:-

query.addCriteria(Criteria.where("stdName").regex("^.{3,50}$"));

MongoDB Aggregation

  • MongoDB Aggregation: Executing a large set of operations over collections of data
  • Aggregation Operation: condition, sort, group, project .. etc.

Aggregation(C) supports:-

  • Creating a new Aggregation object
  • Providing conditional test
  • Supports data sort
  • Execute field projections
  • Converts source format to result class type
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document
public class Student {
    @Id
    private Integer stdId;
    private String stdName;
    private Double stdFee;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MyResult {
    private String stdName;
    private Double stdFee;
}
package com.knowprogram.demo.runner;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Component;

import com.knowprogram.demo.model.MyResult;
import com.knowprogram.demo.model.Student;

@Component
public class Test2Runner implements CommandLineRunner {
    
    @Autowired
    private MongoTemplate mt;

    @Override
    public void run(String... args) throws Exception {
        mt.save(new Student(12, "C", 4.3));    
        mt.save(new Student(13, "D", 5.3));
        mt.save(new Student(14, "E", 6.3));
        
        // mongoDB aggregation
        Aggregation ag = Aggregation.newAggregation(
                Aggregation.match(Criteria.where("stdFee").gt(1.1)),
                Aggregation.sort(Direction.DESC, "stdName"),
                Aggregation.project("stdName", "stdFee")
            ); 
        
        // execute
        // Method syntax:- aggregate(aggregationObject, source, expectedResult.class)
        mt.aggregate(ag, Student.class, Student.class)
          .forEach(System.out::println);
        // gives:- Student(stdId=14, stdName=E, stdFee=6.3)
        // stdId will come by default
        
        // if we want only stdName, and stdFee in result.
        mt.aggregate(ag, Student.class, MyResult.class)
          .forEach(System.out::println);
        // gives:- MyResult(stdName=E, stdFee=6.3)
    }

}

Spring Boot MongoDB With Lookup process using DBRef

Previously we have developed an application using DBRef with Employee, Department, and Project model classes we will use that here.

> db.employee.find()
[
  {
    _id: 320,
    empName: 'Rocco',
    empSal: 600,
    dob: DBRef('department', 50601),
    pobs: [ DBRef('project', 101), DBRef('project', 102) ],
    _class: 'com.knowprogram.demo.model.Employee'
  },
  {
    _id: 321,
    empName: 'Anna',
    empSal: 600,
    dob: DBRef('department', 50602),
    pobs: [ DBRef('project', 102), DBRef('project', 103) ],
    _class: 'com.knowprogram.demo.model.Employee'
  }
]

Let us see how to perform the Aggregation concept on DBRef.

@Component
@Order(2)
public class DataFetchRunner implements CommandLineRunner {

    @Autowired
    private MongoTemplate mt;

    @Override
    public void run(String... args) throws Exception {
        Aggregation aggr = Aggregation.newAggregation(
                Aggregation.match(Criteria.where("_id").is(320)),
                Aggregation.sort(Direction.DESC, "empName"),
                Aggregation.project("empName", "addr","dob", "pobs")
            );
        
        List<Employee> list = mt.aggregate(aggr, "employee", Employee.class)
                .getMappedResults();
        list.forEach(System.out::println);
          

    }

}

Output:-

See more about aggregation in MongoDB:- Aggregation

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!

Leave a Comment

Your email address will not be published. Required fields are marked *