The elasticsearch document has "flattened" fields that can contain one or more pairs of "name":"value". For example, the "flattened" fields "genre" and "countries" look like this: "genres": [ { "uuidGenre": "28e71bf4-21cd-49c0-a0ca-4913b4b50d86", "genreName": "Comedy" }, { "uuidGenre": "fe6b5d15-bf73-4b34-a02e-13d110c89a3f", "genreName": "Fantastic" }
"countries": [
{
"uuidCountry": "ee88f16d-8492-42d8-8dff-3cd0f10d7121",
"countryName": "Can"
},
{
"uuidCountry": "ee88f16d-0987-42d8-8dff-3cd0f10d7121",
"countryName": "India"
}
To search for a document, a query may contain one or more selection criteria for such "flattened" fields. For example, for selection by the "genres" field, the request may contain only one "uuidGenre" value, and for the "countries" field, there may be more than one "uuidCountry" value. Thus, the selection should include documents that match at least one criterion of the request. But if the criterion for strict compliance is applied - "age":"18+", then only documents with the criterion "age": "18+" should get into the selection, which partially or completely meet the criteria for "uuidGenre" and "uuidCountry". Such a request directly to the index in Postman looks like this:
{ "query":{
"bool":{
"must":[
{"match":{"age":18}},
{"bool":{
"should":[
{ "terms":
{ "genres.uuidGenre": ["c6bee588-3b47-4307-ba00-40764d50a57a", "fe6b5d15-bf73-4b34-a02e-13d110c89a3f"] } },
{ "terms": { "countries.uuidCountry": ["24cb3786-d85c-418c-af90-c719c2a5a796" , "ee88f16d-8492-42d8-8dff-3cd0f10d7121"] } }
]
}
}
]
}}}
and it gives the expected result. To create an API in java, I use Query filmQuery = NativeQuery.builder(). The request looks like this:
Query filmQuery = NativeQuery.builder()
.withQuery(q1 -> q1
.bool(bq -> {
if (titleInLowercase.equals("")) {
bq.must(ma -> ma.matchAll(m -> m));
sortParam.set(Sort.by("title.keyword").ascending());
} else if ((titleInLowercase.length()) == 1) {
bq.must(m -> m.prefix(p -> p
.field("title")
.value(titleInLowercase))
);
sortParam.set(Sort.by("title.keyword").descending());
} else if ((titleInLowercase.length()) >= 2) {
bq.must(m -> m.match(ma -> ma
.field("title")
.query(titleInLowercase)
));
sortParam.set(Sort.by("title.keyword").ascending());
}
if (!frontRequest.isNull("genres") && finalValueListGenres.size() > 1) {
for (Object uuid : finalValueListGenres) {
bq.should(m -> m
.term(t -> t
.field("genres.uuidGenre")
.value(String.valueOf(uuid))
));
}
}
if (!frontRequest.isNull("countries") && finalValueListCountries.size() > 1) {
for (Object uuid : finalValueListCountries) {
bq.should(m -> m
.term(t -> t
.field("countries.uuidCountry")
.value(String.valueOf(uuid))
));
}
}
if (!frontRequest.isNull("language") && finalValueListLanguage.size() > 1) {
for (Object uuid : finalValueListLanguage) {
bq.should(m -> m
.term(t -> t
.field("language_id.uuidLanguage")
.value(String.valueOf(uuid))
));
}
}
bq.minimumShouldMatch("3");
return bq;
}))
.withFilter(f -> f
.bool(b -> {
if (!frontRequest.isNull("language") && finalValueListLanguage.size() == 1) {
for (Object uuid : finalValueListLanguage) {
b.must(fbm -> fbm
.term(t -> t
.field("language_id.uuidLanguage")
.value(String.valueOf(uuid))));
}
}
if (!frontRequest.isNull("genres") && finalValueListGenres.size() == 1) {
b.must(bm -> bm
.term(t -> t
.field("genres.uuidGenre")
.value(String.valueOf(finalValueListGenres.get(0)))));
}
if (!frontRequest.isNull("countries") && finalValueListCountries.size() == 1) {
for (Object uuid : finalValueListCountries) {
b.must(m -> m
.term(ma -> ma
.field("countries.uuidCountry")
.value(String.valueOf(uuid))));
}
}
if (!frontRequest.isNull("age")) {
b.filter(m -> m
.term(t -> {
try {
return t
.field("age")
.value(frontRequest.getInt("age"));
} catch (JSONException e) {
throw new RuntimeException(e);
}
}));
}
if (!frontRequest.isNull("is_popular")) {
b.filter(m -> m
.term(t -> {
try {
return t
.field("is_popular")
.value(frontRequest.getBoolean("is_popular"));
} catch (JSONException e) {
throw new RuntimeException(e);
}
}));
}
if (!frontRequest.isNull("is_new")) {
b.filter(m -> m
.term(t -> {
try {
return t
.field("is_new")
.value(frontRequest.getBoolean("is_new"));
} catch (JSONException e) {
throw new RuntimeException(e);
}
}));
}
if (!frontRequest.isNull("type")) {
b.filter(m -> m
.term(t -> {
try {
return t
.field("mediaTypeId")
.value(frontRequest.getInt("type"));
} catch (JSONException e) {
throw new RuntimeException(e);
}
}));
}
if (!frontRequest.isNull("years")) {
for (String years : finalYearsList) {
String yearsOfReleaseDate = String.valueOf(years);
java.time.LocalDate beginningDate = java.time.LocalDate.parse(yearsOfReleaseDate + "-01-01");
java.time.LocalDate beginningDatePlusYear = beginningDate.plusYears(1);
JsonData jsonBeginningDate = JsonData.of(String.valueOf(beginningDate));
JsonData jsonBeginningDatePlusYear = JsonData.of(String.valueOf(beginningDatePlusYear));
b.filter(m -> m
.range(ma -> ma
.field("release_date")
.gte(jsonBeginningDate)
.lt(jsonBeginningDatePlusYear)
)
);
}
}
return b;
}
))
.withSort(sortParam.get())
.withPageable(Pageable.ofSize(pageSize))
.build();
I can't find a way to use "terms" in a Query query... I would appreciate the help of a novice javist
your are already using a
termquery, for examplethe query builder has a
terms()method as well