cagdasalagoz
cagdasalagoz

Reputation: 499

Creating a TermQuery with a List by using Elasticsearch Java API Client

I am trying to convert some Java High Level REST Client code to new Elasticsearch Java API Client.

I want to convert this query which retrieves the contents if the id is equal to 10 or 20.

SearchRequest searchRequest = new SearchRequest().indices(indexName);

    List<Long> ids = new ArrayList<>();
    ids.add(10l);
    ids.add(20l);

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    searchSourceBuilder.query(QueryBuilders.boolQuery()
        .must(QueryBuilders.termQuery("id", ids)));

        searchRequest.source(searchSourceBuilder);

With the new Java API Client I've built something like this.

TermsQueryField termsQueryField = new TermsQueryField.Builder()
         .value(/*Expects List<FieldValue>*/)
         .build();

TermsQuery idTerms = new TermsQuery.Builder()
        .field("id")
        .terms(termsQueryField)
        .build();

Query idQuery = new Query.Builder()
        .terms(idTerms)
        .build();

BoolQuery boolQuery = new BoolQuery.Builder()
        .must(idQuery)
        .build();

Query query = new Query.Builder()
        .bool(boolQuery)
        .build();

SearchRequest searchRequest = new SearchRequest.Builder()
        .index(indexName)
        .query(query)
        .build();

I can add the termQuery options for single values but I could not find a way to add a list to the query.

I've came across with TermsQuery but that requires the values to be set as a List<FieldValue> so that's not very helpful.

Note: I know I can use lambda expressions for constructing these objects but I am trying to be as verbose as possible until I figure out how to use the new client.

Upvotes: 3

Views: 9081

Answers (3)

Prabhakar Chaudhary
Prabhakar Chaudhary

Reputation: 1

The below code is also working.

TermsQueryField countryTerms = new TermsQueryField.Builder()
.value(countries.stream().map(FieldValue::of).toList())
.build();

SearchRequest sr = SearchRequest.of(s -> s
            .query(q -> q
                    .bool(bCtry -> bCtry
                            .should(shdCtry -> shdCtry
                                    .terms(tCtry -> tCtry
                                            .field("country")
                                            .terms(countryTerms)
                                    )
                            )
                    )
            )
    );

Upvotes: 0

bluecheese
bluecheese

Reputation: 71

You can use boolQuery like this

boolQuery().apply {
            ids.forEach {
                should(matchQuery("test.id", it))
            }
        }

Above solution has a limit on the criterias to add. Otherwise use

(termsQuery("FIELD", [value1, value2,value3])

Upvotes: 0

JWeberhofer
JWeberhofer

Reputation: 71

Using streams seems currently to be the simplest way to create the list of terms:

List<String> countries = List.of("afg", "aus");

TermsQueryField countryTerms = new TermsQueryField.Builder()
    .value(countries.stream().map(FieldValue::of).toList())
    .build();

SearchRequest sr = SearchRequest.of(s -> s
    .query(q -> q
        .bool(b -> b 
            .filter(mCtry -> mCtry
                .bool(bCtry -> bCtry
                    .should(shdCtry -> shdCtry
                        .terms(tCtry -> tCtry
                            .field("country")
                            .terms(countryTerms)
                        )
                    )
                )
            )
        )
    )
);

Upvotes: 5

Related Questions