elasticsearch 在NativeQuery中使用术语搜索多个可选匹配项

zsbz8rwp  于 2023-10-17  发布在  ElasticSearch
关注(0)|答案(2)|浏览(99)

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能帮助我

1sbrub3j

1sbrub3j1#

您已经在使用term查询,例如

bq.should(m -> m
     .term(t -> t
       .field("countries.uuidCountry")
       .value(String.valueOf(uuid))
    ));

查询生成器也有一个terms()方法

k4ymrczo

k4ymrczo2#

在熟悉了Field Value、TermsQueryField和TermsQuery类的规范之后,出现了这样一个解决方案:

Query filmQuery = NativeQuery.builder()
            .withQuery(q -> q.bool(b -> {
                if (titleInLowercase.equals("")) {
                b.must/term/should...}
                b.filter(m -> m.bool(mb -> {
                    if (!frontRequest.isNull("countries") && finalValueListCountries.size() > 1) {
                        System.out.println("valueListCountries.size() > 1 ");
                        List<FieldValue> fieldValueList = new ArrayList<>();
                        for (String uuid :
                                finalValueListCountries) {
                            FieldValue.Builder fieldValueBuilder = new FieldValue.Builder();
                            fieldValueBuilder.stringValue(uuid);
                            FieldValue fieldValue = fieldValueBuilder.build();
                            fieldValueList.add(fieldValue);
                        }
                        TermsQueryField termsQueryField = new TermsQueryField.Builder()
                                .value(fieldValueList)
                                .build();
                        mb.filter(s -> s
                                .terms(t -> t
                                        .field("countries.uuidCountry")
                                        .terms(termsQueryField)));
                    }

如果不是放弃学习java的想法,我会很感激你的推荐

相关问题