'spring-data-mongo - optional query parameters?
I am using spring-data mongo with the JSON based query methods, and am unsure how to allow optional parameters in a search query.
For instance - say I had the following function
@Query("{ 'name' : {$regex : ?0, $options : 'i'}, 'createdDate' : {$gte : ?1, $lt : ?2 }} }")
List<MyItem> getItemsLikeNameByDateRange(String name, Date startDateRange, Date endDateRange);
-but I didnt want to apply the name regex match, or not apply a date range restriction if NULL values were passed to the method.
At the moment it looks like I might have to build the query using the mongoTemplate.
Are there any alternatives - or is using mongoTemplate the best option?
Thanks
Solution 1:[1]
In addition to Archimedes's answer:
If you need the count of matched documents, replace $where with $expr.
@Query("{ $or : [ { $expr: { $eq: ['?0', 'null'] } } , { field : ?0 } ] }")
Page<Something> findAll(String query, Pageable pageable);
Solution 2:[2]
Filtering out parts of the query depending on the input value is not directly supported. Nevertheless it can be done using @Query the $and and operator and a bit of SpEL.
interface Repo extends CrudRepository<MyItem,...> {
@Query("""
{ $and : [
?#{T(com.example.Repo.QueryUtil).ifPresent([0], 'name')},
?#{T(com.example.Repo.QueryUtil).ifDateBetween([1], [2], 'startDate')},
...
]}
""")
Page<MyItem> findDataSearchParams(String name, String city, ...)
class QueryUtil {
public static Document ifPresent(Object value, String property) {
if(value == null) {
return new Document("$expr", true); // always true
}
return new Document(property, value); // eq match
}
public static Document ifDateBetween(Object value1, Object value2, String property) {
// ...
}
}
// ...
}
Instead of addressing the target function via the T(...) Type expression writing an EvaluationContextExtension (see: json spel for details) allows to get rid of repeating the type name over and over again.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Paul Lam |
| Solution 2 | Christoph Strobl |
