EzyMongo Introduction

1. Introduce EzyMongo

EzyMongo (Easy going to Mongo Interaction) is a framework support to interact to MongoDB, It supports:
  1. Transparently map your Java entities to MongoDB documents and back
  2. Query, update, delete and aggregation by query string
  3. Annotation driven

2. Structure of EzyMongo

  1. Database Context: wraps MongoClient, DataBinding. Manages repositiors, QueryManager and DataSerializers. Provides function to get repostiories, queries and serializers
  2. Repostiories: Manages all repostiores by name and type
  3. QueryManager: Manages all queries, collects queries from annotations and deverloper set
  4. DataSerializers: Manages all data serializers and deserializers, provide a way to allow deverloper custom and set their serializers and deverlopers
  5. Repostiory: converts queries, data and calls to MongoDB

3. Install EzyMongo

1. To create EzyMongo we need add dependency
The latest version can be found in the Maven Central repository.
2. To use EzyMongo you need config to create repositories
You can use ezyfox-boot-autoconfigure by add to your pom.xml:
Or because with some reason, you can not use ezyfox-boot-autoconfigure you can config like this:
import com.mongodb.MongoClient;
import com.tvd12.ezydata.database.EzyDatabaseContext;
import com.tvd12.ezydata.mongodb.EzyMongoDatabaseContextBuilder;
import com.tvd12.ezydata.mongodb.loader.EzySimpleMongoClientLoader;
import com.tvd12.ezyfox.annotation.EzyProperty;
import com.tvd12.ezyfox.bean.EzyBeanConfig;
import com.tvd12.ezyfox.bean.EzyPackagesToScanAware;
import com.tvd12.ezyfox.bean.EzySingletonFactory;
import com.tvd12.ezyfox.bean.EzySingletonFactoryAware;
import com.tvd12.ezyfox.bean.annotation.EzyConfigurationBefore;
import com.tvd12.ezyfox.util.EzyPropertiesAware;
import lombok.Setter;

import java.util.Map;
import java.util.Properties;

public class EzyMongoConfiguration implements
        EzySingletonFactoryAware {
    private String databaseName;
    private Properties properties;
    private EzySingletonFactory singletonFactory;
    public void config() {
        EzyDatabaseContext databaseContext = newMongodbDatabaseContext();
        Map<String, Object> repos = databaseContext.getRepositoriesByName();
        for (String repoName : repos.keySet()) {
            singletonFactory.addSingleton(repoName, repos.get(repoName));
    private EzyDatabaseContext newMongodbDatabaseContext() {
        EzyMongoDatabaseContextBuilder builder = new EzyMongoDatabaseContextBuilder()
        return builder.build();
    protected MongoClient newMongoClient() {
        return EzySimpleMongoClientLoader.load(properties);
3. You can add to your configuration file like this:
# for application.yaml
    uri: mongodb://ezydata_mongo:ezydata_mongo@localhost:27017/ezydata-mongo
    database: ezydata-mongo
        case: UNDERSCORE
        ignored_suffix: Entity
# for application.properties

4. Example

Let’s say we need create an http server application to manage a book store (Category, Author and Book), we need 6 apis
  • api/v1/author/add: Add an author
  • api/v1/category/add: Add a category
  • api/v1/book/add: Add a book
  • api/v1/books/{bookId}: Get a book by id
  • api/v1/books: Get a list of books
  • apiv1/books/expected-revenue:
4.1 Create entities class
To store Category, Author and Book to MongoDB, we need create 3 entities
import com.tvd12.ezydata.database.annotation.EzyCollection;
import com.tvd12.ezyfox.annotation.EzyId;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

public class Category {
    private long id;
    private String name;

public class Author {
    private long id;
    private String name;

public class Book {
    private Long id;
    private Long categoryId;
    private Long authorId;
    private String name;
    private BigDecimal price;
    private LocalDate releaseDate;
    private LocalDateTime releaseTime;
4.2 Create repositories
We need create 3 repositories for 3 entities
import com.tvd12.ezydata.example.mongo.entity.Category;
import com.tvd12.ezydata.mongodb.EzyMongoRepository;
import com.tvd12.ezyfox.database.annotation.EzyRepository;

public interface CategoryRepository extends EzyMongoRepository<Long, Category> {
    Category findByName(String name);
import com.tvd12.ezydata.example.mongo.entity.Author;
import com.tvd12.ezydata.mongodb.EzyMongoRepository;
import com.tvd12.ezyfox.database.annotation.EzyRepository;

public interface AuthorRepository extends EzyMongoRepository<Long, Author> {
import java.util.List;

import com.tvd12.ezydata.database.annotation.EzyQuery;
import com.tvd12.ezydata.example.mongo.entity.Book;
import com.tvd12.ezydata.example.mongo.result.SumBookPriceResult;
import com.tvd12.ezydata.mongodb.EzyMongoRepository;
import com.tvd12.ezyfox.database.annotation.EzyRepository;
import com.tvd12.ezyfox.util.Next;

public interface BookRepository extends EzyMongoRepository<Long, Book> {

    Book findByNameAndAuthorId(String name, Long authorId);

    List<Book> findBooks(Next next);

    @EzyQuery("{$query:{name:{$lt:?0}}, $orderby:{name:1}}")
    List<Book> findByNameLt(String name, Next next);

    @EzyQuery("{$query:{name:{$gt:?0}}, $orderby:{name:1}}")
    List<Book> findByNameGt(String name, Next next);

    @EzyQuery("[{ $group: { _id : 'sum', sum : { $sum: {$toDecimal: '$price'}} } }]")
    SumBookPriceResult sumPrice();
4.3 Save entities
Save a category, see more details
Category category = new Category(
Save an author, see more details
Author author = new Author(
return author;
Save a book, see more details
val bookId = maxIdRepository.incrementAndGet("book");
val book = requestToEntityConverter.toBookEntity(request, bookId);
4.4 Query data
Find a category by id, see more details
Category category = categoryRepository.findById(request.getCategoryId());
Find an author by id, see more details
Author author = authorRepository.findById(request.getAuthorId());
Find a book by name and author id, see more details
Book existedBook = bookRepository.findByNameAndAuthorId(
Get sum of all book prices, see BookRepository and BookController to get more details
@EzyQuery("[{ $group: { _id : 'sum', sum : { $sum: {$toDecimal: '$price'}} } }]")
SumBookPriceResult sumPrice();
4.5 Update data
You can update data with a function has update prefix like this:
@EzyQuery("{$query: {_id : 4}, $update: {$set: {category: ?0}}}")
void updateCategory(String category);
And you can delete data with a function has delete prefix like this:
@EzyQuery("{_id : {$gt: ?0}}")
void deleteByIdGt(int id);
Full source code available on Github

5. Conclusion

With EzyMongo you will work with MongoDB lot easier and more native. With query string, you will don't need care about bson, criteria and you will reduce a lot of your source code


You can take a look EzyMongo configuration