EzyMongo Introduction

1. Introduct to 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

To create EzyMongo we need add dependency
<dependency>
    <groupId>com.tvd12</groupId>
    <artifactId>ezydata-mongodb</artifactId>
    <version>1.1.4</version>
</dependency>
The latest version can be found in the Maven Central repository.

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;

@Getter
@Setter
@EzyCollection
@AllArgsConstructor
@NoArgsConstructor
public class Category {
    @EzyId
    private long id;
    private String name;
}

@Getter
@Setter
@EzyCollection
@AllArgsConstructor
@NoArgsConstructor
public class Author {
    @EzyId
    private long id;
    private String name;
}

@Getter
@Setter
@EzyCollection
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    @EzyId
    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;

@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;

@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;

@EzyRepository
public interface BookRepository extends EzyMongoRepository<Long, Book> {

    Book findByNameAndAuthorId(String name, Long authorId);

    @EzyQuery("{$orderby:{name:1}}")
    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(
    maxIdRepository.incrementAndGet("category"),
    request.getCategoryName()
);
categoryRepository.save(category);
Save an author, see more details
Author author = new Author(
    maxIdRepository.incrementAndGet("author"),
    request.getAuthorName()
);
authorRepository.save(author);
return author;
Save a book, see more details
val bookId = maxIdRepository.incrementAndGet("book");
val book = requestToEntityConverter.toBookEntity(request, bookId);
bookRepository.save(book);
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(
    request.getBookName(),
    request.getAuthorId()
);
Get sum of all book prices, see BookRepository and BookController to get more details
@EzyQuery("[{ $group: { _id : 'sum', sum : { $sum: {$toDecimal: '$price'}} } }]")
SumBookPriceResult sumPrice();
bookRepository.sumPrice().getSum()
Full source code available on Github

5. Conclusion

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