Using MongoDB query syntax to query Relational Database in Java

Mohammed Hewedy
2 min readMar 24, 2021

Spring Data JPA provides a lot of features on top of JPA. Such as Query methods, Query by examples, and a lot more.

It also integrates with JPA Specifications, QueryDSL, Jooq, and other fantastic libraries.

There’s a specific use-case that exists in most applications which is the need to make the user search by multiple criteria for an entity and its related associations. This is where “Spring Data JPA Mongodb Expressions excels.

Spring Data JPA MongoDB Expressions allows you to use MongoDB query syntax to send the queries as JSON string typically from the frontend app to a Rest API and then to the Repository layer.

Here’s an example query that users can send from the frontend:

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

will be translated to:

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

As you see, it uses the same notation of the initiative and simple-to-use MongoDB query language with features such as ANDing, ORing, and joining entities.

So How to start?

To use the library you need to configure your spring boot project to use The Expression API:

@SpringBootApplication
@EnableJpaRepositories(repositoryBaseClass = ExpressionsRepositoryImpl.class)
public class Application { … }

Then, you need to extend ExpressionsRepository :

@Repository
public interface EmployeeRepository extends ExpressionsRepository<Employee, Long> {
}

And finally, you need to add Expressions as a parameter to your Controller search method:

@PostMapping("/search")
public ResponseEntity<Page<EmployeeDto>> search(@RequestBody Expressions expressions, Pageable pageable) {

return ok().body(
employeeRepository.findAll(expressions, pageable).map(employeeMapper::toDto)
);
}

Sample MongoDB-like queries to be passed to the Controller:

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

Also, nested objects (join) are supported:

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

--

--