Search code examples
elasticsearchelasticsearch-jest

Elasticsearch Jest client add condition to json query


I am using Elasticsearch 6.3 with Jest client 6.3 (Java API)

Search search = new Search.Builder(jsonQueryString)
                    .addIndex("SOME_INDEX")
                    .build();
SearchResult result = jestClient.execute(search);

And this is my sample JSON query

{
"query": {
    "bool" : {
        "filter": {
            "match" :{ 
                "someField" : "some value" 
                }
            }
        }
    }
}

The JSON query string is accepted as a POST request body and then passed to the Jest client. Before I can execute the json query on the Jest client, I need to add conditions to the query for e.g.

{
"query": {
    "bool" : {
        "filter": {
            "match" :{ 
                "someField" : "some value" 
                }
            }
        },
        "must": {
            "match" :{ 
                "systemField" : "pre-defined value" 
                }
            }
        }
    }
}

Is there an API that allows to parse the JSON query and add conditions to it before it can be executed on Jest client? The JSON query can be any query supported by Query DSL and not necessarily contain bool condition. I need to add a pre-defined condition to the query. I appreciate any help on this. Thanks very much.


Solution

  • There is no out of the box Elasticsearch or Jest API to achieve the above, the workaround I implemented is using Jackson ObjectMapper

    // convert the search request body into object node
    ObjectNode searchRequestNode = objectMapper.readValue(queryString, ObjectNode.class);
    // extract the query
    String query = searchRequestNode.get("query").toString();
    
    // wrap the original query and add conditions
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.must(QueryBuilders.wrapperQuery(query));
    boolQueryBuilder.filter(QueryBuilders.termsQuery("fieldA", listOfValues));
    boolQueryBuilder.filter(QueryBuilders.termQuery("fieldB", value));
    
    // convert querybuilder to json query string
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(queryBuilder);
    String queryWithFilters = searchSourceBuilder.toString();
    
    // convert json string to object node
    ObjectNode queryNode = objectMapper.readValue(queryWithFilters, ObjectNode.class);
    
    // replace original query with the new query containing added conditions 
    searchRequestNode.set("query", queryNode.get("query"));
    String finalSearchRequestWithOwnFilters = searchRequestNode.toString();