rashadsaif / spring-data-jpa-mongodb-expressions

Allows you to use the MongoDB query syntax to query your relational database.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Spring Data JPA MongoDB Expressions

Java CI with Maven codecov javadoc Join the chat at https://gitter.im/spring-data-jpa-mongodb-expressions/community

Parses (a subset of) MongoDB expressions and convert them to Specifications to be used with Spring-Data-JPA ๐ŸŽ‰.

โšก๏ธ Why?

spring-data-jpa-mongodb-expressions allows you to use the MongoDB query syntax to query your relational database. This is specially useful to build dynamic queries from the frontend app (js/typescript).

So, you can build the mongodb query-like json from the frontend app and pass it to the controller, and then optionally you enrich it with addtional conditions and pass it to the repository layer, in which the monogodb query will be translated automatically to JPA specification and executed.

๐Ÿ“š API

This library provides an single interface ExpressionsRepository to be extended by your application repositories:

public interface ExpressionsRepository<T, ID> extends JpaRepository<T, ID> {

    List<T> findAll(Expressions expressions);

    List<T> findAll(Expressions expressions, Sort sort);

    Page<T> findAll(Expressions expressions, Pageable pageable);
    
    long count(Expressions expressions);
}

See javadoc for more information.

๐Ÿš€ How to start

  1. You need to customize the base repository to be the ExpressionsRepositoryImpl.
@Configuration
@EnableJpaRepositories(repositoryBaseClass = ExpressionsRepositoryImpl.class)
class ApplicationConfiguration { โ€ฆ }
  1. Change the parent repository of your JPA repositories:
@Repository
public interface EmployeeRepository extends ExpressionsRepository<Employee, Long> {
}
  1. Modify the search controller to accept Expressions in its parameter list:
@PostMapping("/search")
public ResponseEntity<Page<EmployeeDto>> search(@RequestBody Expressions expressions, Pageable pageable) {

    // optional part
    expressions.and(Expression.of("departementId", $eq, getCurrentUserDeptId()));
    // add additional filters by ANDing or ORing more expression
    
    return ok().body(
                employeeRepository.findAll(expressions, pageable).map(employeeMapper::toDto)
        );
}

And that's it, you can now send Mongodb-like json queries to the api.

๐Ÿฎ Examples json queries:

The following is an example expressions that could be sent to the Controller Rest Apis, and will be deserialized into the Expressions object.

1-

Expression:

{
  "lastName": "ibrahim",
  "$and": [
    {"birthDate": {"$gt": "1981-01-01"}},
    {"birthDate": {"$lte": "1985-10-10"}}
  ]
}

output:

... where last_name=? and birth_date>? and birth_date<=?

2-

Expression:

{
  "$or": [
    {"lastName": "ibrahim"},
    {
      "$and": [
        {"firstName": "mostafa"},
        {"birthDate": {"$gt": "1990-01-01"}}
      ]
    }
  ]
}

output:

... where last_name = ? or first_name = ? and birth_date > ?

3-

Expression (joins):

{
  "lastName": "ibrahim",
  "department.name": {"$contains":  "sw"}
}

output:

... from employee e inner join department d on e.department_id=d.id where e.last_name=? and d.name like ?

For a list of json queries see :

  1. the resources directory
  2. ExpressionsRepositoryImplTest.java
  3. Mongodb docs as a reference for the queries.

๐Ÿน Operators

The following is a list of supported operators:

Operator Description
$eq col = val (if val is null then => col is null)
$ne col <> val (if val is null then => col is not null)
$ieq lower(col) = lower(val)
$gt col > val
$gte col >= val
$lt col < val
$lte col <= val
$start col like 'val%'
$end col like '%val'
$contains col like '%val%'
$istart lower(col) like 'lower(val)%'
$iend lower(col) like '%lower(val)'
$icontains lower(col) like '%lower(val)%'
$in col in (val1, val2, ...)
$nin col not in (val1, val2, ...)
$or expr1 or expr2
$and expr1 and expr2

โš™๏ธ Install

<dependency>
  <groupId>com.github.mhewedy</groupId>
  <artifactId>spring-data-jpa-mongodb-expressions</artifactId>
  <version>0.0.2</version>
</dependency>

Compatibility with Spring-Data-JPA

spring-data-jpa-mongodb-expressions depends mostly on public APIs from JPA and Spring-data-jpa projects, such as javax.persistence.criteria.Predicate, org.springframework.data.domain.Pageable and org.springframework.data.jpa.domain.Specification.

So unless the public APIs for JPA and Spring-data-jpa don't change, it is safe to use spring-data-jpa-mongodb-expressions.

Also spring-data-jpa-mongodb-expressions declares spring-boot-starter-data-jpa as an optional dependency, which means it isn't a transitive dependency and no dependencies will be transferred to your project (from spring or what so ever) as a result of using spring-data-jpa-mongodb-expressions.

๐ŸŽญ How to build the query on Frontend?

See this snippet to see how to build the query from js.

๐ŸŽ– Special Thanks

Special thanks to Rashad Saif and Hamada Elnoby for helping in the design, inspring with ideas, and for doing the review for the code.

About

Allows you to use the MongoDB query syntax to query your relational database.


Languages

Language:Java 100.0%