我需要更改当前代码搜索,因为它看起来太慢,一次搜索大约需要15秒。

我们正在寻找参数



我有以下代码:

private NativeSearchQueryBuilder getSearchQuery(AuctionIndexSearchParams searchParams, Pageable pageable) {
        final List<FilterBuilder> filters = Lists.newArrayList();
        final NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery());

        Optional.ofNullable(searchParams.getCategoryId()).ifPresent(v -> filters.add(boolFilter().must(termFilter("cat", v))));
        Optional.ofNullable(searchParams.getCurrency()).ifPresent(v -> filters.add(boolFilter().must(termFilter("curr", v))));
        Optional.ofNullable(searchParams.getTreeCategoryId()).ifPresent(v -> filters.add(boolFilter().must(termFilter("tcat", v))));
        Optional.ofNullable(searchParams.getUid()).ifPresent(v -> filters.add(boolFilter().must(termFilter("uid", v))));
        final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //access for many uids
        if (searchParams.getUids() != null) {
            Optional.ofNullable(searchParams.getUids().split(",")).ifPresent(v -> {
            filters.add(boolFilter().must(termsFilter("uid", v)));
        });
        }
        //access for many categories
        if (searchParams.getCategories() != null) {
            for(String category : searchParams.getCategories().split(",")){
                 Optional.ofNullable(searchParams.getCategories().split(",")).ifPresent(v -> {
            filters.add(boolFilter().must(termsFilter("cat", v)));
        });
             }
        }

        if (searchParams.getItemId() != null) {
            boolQueryBuilder.must(queryStringQuery(searchParams.getItemId()).field("_id"));
        }

        if (Optional.ofNullable(searchParams.getTitle()).isPresent()) {
            boolQueryBuilder.must(queryStringQuery(searchParams.getTitle()).analyzeWildcard(true).field("title"));
        }

        if (Optional.ofNullable(searchParams.getStartDateFrom()).isPresent()
                || Optional.ofNullable(searchParams.getStartDateTo()).isPresent()) {
            filters.add(rangeFilter("start_date").from(searchParams.getStartDateFrom()).to(searchParams.getStartDateTo()));
        }

        if (Optional.ofNullable(searchParams.getEndDateFrom()).isPresent()
                || Optional.ofNullable(searchParams.getEndDateTo()).isPresent()) {
            filters.add(rangeFilter("end_date").from(searchParams.getEndDateFrom()).to(searchParams.getEndDateTo()));
        }

        if (Optional.ofNullable(searchParams.getPriceFrom()).isPresent()
                || Optional.ofNullable(searchParams.getPriceTo()).isPresent()) {
            filters.add(rangeFilter("price").from(searchParams.getPriceFrom()).to(searchParams.getPriceTo()));
        }

        searchQuery.withQuery(boolQueryBuilder);

        FilterBuilder[] filterArr = new FilterBuilder[filters.size()];
        filterArr = filters.toArray(filterArr);
        searchQuery.withFilter(andFilter(filterArr));

        if (searchParams.getOrderBy() != null && searchParams.getOrderDir() != null) {
            if (searchParams.getOrderDir().toLowerCase().equals("asc")) {
                searchQuery.withSort(SortBuilders.fieldSort(searchParams.getOrderBy()).order(SortOrder.ASC));
            } else {
                searchQuery.withSort(SortBuilders.fieldSort(searchParams.getOrderBy()).order(SortOrder.DESC));
            }
        }

        if (pageable != null) {
            searchQuery.withPageable(pageable);
        }
        return searchQuery;
    }

搜索持续15秒。 16k记录。

我们正在寻找参数



搜索持续15秒。 800条记录

我们正在寻找以下参数:



我将代码更改为(look boolQueryBuilder):
private NativeSearchQueryBuilder getSearchQuery(AuctionIndexSearchParams searchParams, Pageable pageable) {
        final List<FilterBuilder> filters = Lists.newArrayList();
        final NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery());

        Optional.ofNullable(searchParams.getCategoryId()).ifPresent(v -> filters.add(boolFilter().must(termFilter("cat", v))));
        Optional.ofNullable(searchParams.getCurrency()).ifPresent(v -> filters.add(boolFilter().must(termFilter("curr", v))));
        Optional.ofNullable(searchParams.getTreeCategoryId()).ifPresent(v -> filters.add(boolFilter().must(termFilter("tcat", v))));
        Optional.ofNullable(searchParams.getUid()).ifPresent(v -> filters.add(boolFilter().must(termFilter("uid", v))));
        final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //access for many uids
        if (searchParams.getUids() != null) {
            for (String user : searchParams.getUids().split(",")) {
                boolQueryBuilder.should(queryStringQuery(user).field("uid"));
            }
        }
        //access for many categories
        if (searchParams.getCategories() != null) {
            for(String category : searchParams.getCategories().split(",")){
                 boolQueryBuilder.should(queryStringQuery(category).field("cat"));
             }
        }

        if (searchParams.getItemId() != null) {
            boolQueryBuilder.must(queryStringQuery(searchParams.getItemId()).field("_id"));
        }

        if (Optional.ofNullable(searchParams.getTitle()).isPresent()) {
            boolQueryBuilder.must(queryStringQuery(searchParams.getTitle()).analyzeWildcard(true).field("title"));
        }

        if (Optional.ofNullable(searchParams.getStartDateFrom()).isPresent()
                || Optional.ofNullable(searchParams.getStartDateTo()).isPresent()) {
            filters.add(rangeFilter("start_date").from(searchParams.getStartDateFrom()).to(searchParams.getStartDateTo()));
        }

        if (Optional.ofNullable(searchParams.getEndDateFrom()).isPresent()
                || Optional.ofNullable(searchParams.getEndDateTo()).isPresent()) {
            filters.add(rangeFilter("end_date").from(searchParams.getEndDateFrom()).to(searchParams.getEndDateTo()));
        }

        if (Optional.ofNullable(searchParams.getPriceFrom()).isPresent()
                || Optional.ofNullable(searchParams.getPriceTo()).isPresent()) {
            filters.add(rangeFilter("price").from(searchParams.getPriceFrom()).to(searchParams.getPriceTo()));
        }

        searchQuery.withQuery(boolQueryBuilder);

        FilterBuilder[] filterArr = new FilterBuilder[filters.size()];
        filterArr = filters.toArray(filterArr);
        searchQuery.withFilter(andFilter(filterArr));

        if (searchParams.getOrderBy() != null && searchParams.getOrderDir() != null) {
            if (searchParams.getOrderDir().toLowerCase().equals("asc")) {
                searchQuery.withSort(SortBuilders.fieldSort(searchParams.getOrderBy()).order(SortOrder.ASC));
            } else {
                searchQuery.withSort(SortBuilders.fieldSort(searchParams.getOrderBy()).order(SortOrder.DESC));
            }
        }

        if (pageable != null) {
            searchQuery.withPageable(pageable);
        }
        return searchQuery;
    }

搜索持续3秒。 16k记录。

我们正在寻找以下参数:



搜索持续3秒。 300万条记录。

看起来这些查询似乎是使用OR组合在一起的,并返回了太多结果。如何更改代码以找到工作作为创建 boolQueryBuilder

对于任何帮助,我将不胜感激!

最佳答案

ElasticSearch的 bool(boolean) 查询的工作方式是:

  • 好吧,must查询必须与找到的文档
  • 匹配
  • should查询只会提高结果分数

  • 如果must匹配,但没有should查询匹配,则仍将返回must的所有结果。

    参见https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html

    根据您的实际搜索需求,您可能希望将对uidtitle的查询的查询包装在另一个and -query:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-and-query.html

    然后,您将具有如下所示的层次结构:
    {
        "bool": {
             "must": {
                 "and": [
                      "query_string": { /* for title */ },
                      "query_string": { /* for uid */ }
                 ]
             },
             "should": [ /* more queries to boost documents with matching fields */ ]
        }
    
    }
    

    通常,我还会质疑对uid使用search query -query的问题。我猜term查询可能会更有效。

    07-26 02:54
    查看更多