Search code examples
javaelasticsearchelasticsearch-java-apielasticsearch-java-api-client

Elasticsearch - Migrating from Java High Level Rest Client to New Java API Client of Version 8.x


I am using the new version 8.13 of Elasticsearch for a new search app and trying to imitate the below kind of logic using the new Java API client instead of using Java High Level Rest client which was deprecated now. I have to perform search from multiple indices including below queries-

1.multiple matchPhrasePrefixQuery like below

BoolQueryBuilder searchTheseFields = QueryBuilders.boolQuery();
for (String searchFields : searchTheseFieldsArray) {
        searchTheseFields .should(QueryBuilders.matchPhrasePrefixQuery(searchFields, **SearchText**));
            }

2.multiple term queries with fileds and values

BoolQueryBuilder filterFields = QueryBuilders.boolQuery();
for (Map.Entry<String, Object> entry : filterTheseFields.entrySet()) {
                filterFields.must(QueryBuilders.termQuery(entry.getKey(), entry.getValue()));
            }

3.multiple range queries

BoolQueryBuilder rangeFilter1 = QueryBuilders.boolQuery();
BoolQueryBuilder rangeFilter2 = QueryBuilders.boolQuery();

rangeFilter1.should(QueryBuilders.rangeQuery(key).gte("gteVal").lte("lteVal"))
                               .should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery(key)));

And finally add all these queries to a single Query Builder like below and call using client.

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(searchTheseFields)
                .must(filterFields)
                .filter(rangeFilter1);

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder);
        searchSourceBuilder.from(data.getFrom());
        searchSourceBuilder.size(data.getSize());
        
SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(passing indices here);
        searchRequest.source(searchSourceBuilder);
        
SearchResponse response = client.search(searchRequest);

Issues I am facing while trying it using new Java Client - BoolQueryBuilder is not there which was used earlier to create different type of queries and aggregate all of them. As @Murat mentioned SearchSourceBuilder is also not there

So,can anyone help me to imitate the above code using new Java API Client of Elasticsearch new version 8 or above, like how We can create multiple different type queries and add all of them to a single query and call it using the client.

Thanks


Solution

  • Finally I have converted the above posted logic from Elasticsearch 7.16.2 Java High Level Rest Client to Elasticsearch 8.13.2 new Java Client.

    1.multiple matchPhrasePrefixQuery

    BoolQuery.Builder searchTheseFields = new BoolQuery.Builder();
    for (String searchFields : searchTheseFieldsArray) {
                searchTheseFields.should(Query.of(q -> q
                        .matchPhrasePrefix(m -> m.field(searchFields).query("searchText"))));
            }
    

    2.multiple term queries with fileds and values

    BoolQuery.Builder filterFields = new BoolQuery.Builder();
    for (Map.Entry<String, Object> entry : filterFieldsList.entrySet()) {
                filterFields.must(Query.of(
                        q -> q.term(t -> t.field(entry.getKey()).value(entry.getValue().toString().toLowerCase()))));
            }
    

    3.multiple range queries

    ArrayList<Query> rangeFilterQueries = new ArrayList<>();
    Query rangeQuery1 = QueryBuilders.range().field(key).gte(JsonData.of(dateRange.get(0)))
                            .lte(JsonData.of(dateRange.get(1))).build()._toQuery();
                    Query notExistsQuery1 = QueryBuilders.bool().mustNot(m -> m.exists(e -> e.field(key))).build()
                            ._toQuery();
                    rangeFilterQueries
                        .add(QueryBuilders.bool().should(rangeQuery1).should(notExistsQuery1).build()._toQuery()); etc...
    

    Building Final query

    BoolQuery.Builder queryBuilder = new BoolQuery.Builder().must(searchTheseFields.build()._toQuery())
                .must(filterFields.build()._toQuery());
    
        for (Query rangeFilterQuery : rangeFilterQueries) {
            queryBuilder.filter(rangeFilterQuery);
        }
    
        Query finalQuery = queryBuilder.build()._toQuery();
    

    Executing the query

    SearchRequest searchRequest = new SearchRequest.Builder().index(indicesToSearchFrom).query(finalQuery)
                .from(offset).size(limit).build();