Spring-boot Optional ArrayList parameter in Json MongoDb Query

Looking in other posts about how to make an optional parameter query with mongodb and parameters inpu as a list I found that it could be done with something like this:

@Query("{ $or : [ { $where: '?0 == null' } , { field : ?0 } ] }")
List<Something> findAll(String query, Pageable pageable);

My query looks like this:

@Query("{ $or : [ { $where: '?3 == null' } ,{ input1 : { $in : ?3 } }], 'input2' : ?4 , 'input3' : ?2 ,'dateInput' : {$gt : ?0, $lte : ?1}}")
List<Entities> findThingsbyInputs(Long initialDate, Long endDate, Integer Input2, List<Integer> input1, Integer input3);

When I use this query and Input1 = ?0 = ArrayList, it work nice if the list is not null, but when ?0 is null an exception is lauched. I can query several input parameters with the list but when null, it doesnt work.

The error message is: Query failed with error code 2 and error message '$in needs an array' on server localhost:27017

Any help? and Thanks in advance

Upvotes: 3

Views: 1241

Answers (1)

Mehdi
Mehdi

Reputation: 1531

I faced the same issue and ended up extending the repository and manually implementing the complex methods.
After debugging I think that the issue is due to the fact that when List<Integer> input1 is null the first or condition { $where: '?3 == null' } passes but then the second one { input1 : { $in : ?3 } } is performed and end up looking like : { input1 : { $in : NULL } } which causes the faced problem.

My solution was to extend the reposiroty, implement the method and manually build the required query. In your case it could be something like :

  @Autowired
  MongoTemplate mongoTemplate;

  List<Entities> findThingsbyInputs(Long initialDate, Long endDate, Integer input2,
                                    List<Integer> input1, Integer input3) {
    Query query = new Query();
    if(initialDate != null) {
      query.addCriteria(where("input1").is(input1));
    }

    query.addCriteria(where("input2").is(input2));
    query.addCriteria(where("input3").is(input3));
    query.addCriteria(new Criteria().andOperator(where("dateInput").gt(initialDate),
        where("dateInput").lt(endDate)));

    return mongoTemplate.find(query, Entities.class);

  }  

A Jira ticket is still not resolved by Spring Team.

Upvotes: 1

Related Questions