Reputation: 499
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
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
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
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