Search code examples
javaelasticsearchelasticsearch-dsl

Elasticsearch Java query with combination of AND/OR


I am trying to write a query in Elasticsearch via Spring and Java (Elasticsearch client).

The query is somewhat like:

SELECT *** FROM elasticsearch_index 
WHERE isActive = 1 AND 
(
   (store_code = 41 AND store_genre IN ('01', '03') ) 
OR (store_code = 40 AND store_genre IN ('02') )
OR (store_code = 42 AND store_genre IN ('05', '06') )
)
AND LATITUDE ...  
AND LONGITUDE...

Please know that the parameters within the outer brackets is a Map<Integer, String[]>, so I would iterate over the map to add to AND + OR condition.

I tried with equivalent Java approach but does not seem to work:

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("isActive", 1));

BoolQueryBuilder orQuery = QueryBuilders.boolQuery();
for (Entry<Integer, String[]> entry : cvsDepoMapping.entrySet()) {
  int key = entry.getKey();
  String[] value = entry.getValue();

  orQuery.must(QueryBuilders.matchQuery("storeCode", key));    
  orQuery.must(QueryBuilders.termsQuery("storeGenre", value)); // IN clause
  boolQueryBuilder.should(orQuery);
}

But neither is this working nor. I am certain of the solution. I am struggling to find the Java equivalent conditions for the above condition.

I am using:

  • Spring Boot 2.1.1.RELEASE
  • Elasticsearch 6.4.3

Solution

  • within your or query you need to put a nested and query for each entry:

    without trying to run it:

    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.must(QueryBuilders.matchQuery("isActive", 1));
    
    BoolQueryBuilder orQuery = QueryBuilders.boolQuery();
    for (Entry<Integer, String[]> entry : cvsDepoMapping.entrySet()) {
    
        BoolQueryBuilder storeQueryBuilder = QueryBuilders.boolQuery();
        int key = entry.getKey();
        String[] value = entry.getValue();
        storeQueryBuilder.must(QueryBuilders.matchQuery("storeCode", key));
        storeQueryBuilder.must(QueryBuilders.termsQuery("storeGenre", value)); // IN clause
    
        orQuery.should(storeQueryBuilder);
    }
    boolQueryBuilder.must(orQuery);