elasticsearch文档有“flattened”字段,可以包含一对或多对“name”:“value”。例如,“genre”和“country”的“扁平化”字段如下所示:“genres”:[ {“uuidGenre”:“28e71bf4-21cd-49c0-a0ca-4913b4b50d86”,“genreName”:“Comedy”},{“uuidGenre”:“fe6b5d15-bf73-4b34-a02e-13d110c89a3f”,“genreName”:太棒了
"countries": [
{
"uuidCountry": "ee88f16d-8492-42d8-8dff-3cd0f10d7121",
"countryName": "Can"
},
{
"uuidCountry": "ee88f16d-0987-42d8-8dff-3cd0f10d7121",
"countryName": "India"
}
为了搜索文档,查询可以包含用于这样的“扁平化”字段的一个或多个选择标准。例如,对于“genres”字段的选择,请求可以仅包含一个“uuidGenre”值,并且对于“countries”字段,可以存在多于一个的“uuidCountry”值。因此,选择应包括与请求的至少一个标准相匹配的文档。但是,如果适用于严格遵守的标准-“年龄”:“18+",那么只有文件与标准“年龄”:“18+”应该进入选择,部分或完全满足“uuidGenre”和“uuidCountry”的标准。在Postman中,这样一个直接指向索引的请求看起来像这样:
{ "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"] } }
]
}
}
]
}}}
它给出了预期的结果。为了在java中创建一个API,我使用QueryfilmQuery = NativeQuery.builder()。请求如下所示:
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();
我找不到在Query查询中使用“terms”的方法.如果有一个新的javist能帮助我
2条答案
按热度按时间1sbrub3j1#
您已经在使用
term
查询,例如查询生成器也有一个
terms()
方法k4ymrczo2#
在熟悉了Field Value、TermsQueryField和TermsQuery类的规范之后,出现了这样一个解决方案:
如果不是放弃学习java的想法,我会很感激你的推荐