【问题标题】:Spring data elasticsearch aggregate sum - price, quantitySpring数据elasticsearch聚合总和-价格、数量
【发布时间】:2016-08-12 17:53:49
【问题描述】:

我想使用 spring data elasticsearch 来聚合数据。我想要聚合sum(price)sum(qty)。我应该在方法.addAggregation 中添加什么来获得特定的结果以及如何获得它?

"properties": {
                        "cat": { "store": true,  "type": "long" }, 
                        "curr": { "index": "not_analyzed",  "store": true,  "type": "string" }, 
                        "end_date": { "store": true,  "type": "long" }, 
                        "price": { "store": true,  "type": "long" }, 
                        "start_date": { "store": true,  "type": "long" }, 
                        "tcat": { "store": true,  "type": "long" }, 
                        "title": { "store": true,  "type": "string" }, 
                        "uid": { "store": true,  "type": "long" }
                    }

我的服务方法如下:

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))));

        //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) {
            Optional.ofNullable(searchParams.getCategories().split(",")).ifPresent(v -> {
                filters.add(boolFilter().must(termsFilter("cat", v)));
            });
        }

        final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        if (Optional.ofNullable(searchParams.getTitle()).isPresent()) {
            boolQueryBuilder.should(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));
searchQuery.addAggregation(AggregationBuilders("price").field("price"));
        Aggregations aggregations = searchTemplate.query(searchQuery.build(), new ResultsExtractor<Aggregations>(){
        @Override
            public Aggregations extract(SearchResponse response) {
                return response.getAggregations();
            }
        });
        return aggreg

ations.asMap();

为什么聚合不能聚合过滤器、布尔值等并为所有记录返回 aggs I thnik?

【问题讨论】:

    标签: java elasticsearch spring-boot spring-data spring-data-elasticsearch


    【解决方案1】:

    使用它来添加聚合并获取结果:

    SearchRequestBuilder searchRequestBuilder = elasticsearchTemplate.client.prepareSearch("index_name")
                .setIndices("index_name")
                .setTypes("type_name").setQuery(searchQuery).addAggregation(AggregationBuilders.stats("sum_of_price").field("price"))
                .addAggregation(AggregationBuilders.sum("sum_of_qty").field("qty"))
        SearchResponse searchResponse = searchRequestBuilder.execute().actionGet()
        Integer priceTotal = (searchResponse.getAggregations().getAsMap().get("sum_of_price").getSum())
    

    【讨论】:

    • 好的,但是如何在spring data elasticsearch中实现呢?看@up
    • 这是spring data ES和Java Api的结合。我觉得应该可以
    • 当尝试获取对象时,它在启动时不起作用 .client searchTemplate 没有它我得到了@Autowired private ElasticsearchTemplate searchTemplate;所以你的例子对我不起作用,我添加的内容返回给我所有的索引总和
    • avg = 303116.9258428293m count = 4289296272, sum = 1300158299997748 它应该少得多,我认为它返回所有总和等。
    【解决方案2】:

    我知道为时已晚,但对于 Spring Data Elasticsearch 代码从之前的答案看起来像这样:

    SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withIndices("index_name")
            .withTypes("type_name")
            .withQuery(searchQuery)
            .addAggregation(AggregationBuilders.sum("sum_of_price").field("price"))
            .addAggregation(AggregationBuilders.sum("sum_of_qty").field("qty")).build();
    
    Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
      @Override
      public Aggregations extract(SearchResponse response) {
        return response.getAggregations();
      }
    });
    
    Sum aggregation = aggregations.get("sum_of_price");
    double priceTotal = aggregation.getValue());
    

    【讨论】:

    • 您忘记在 NativeSearchQueryBuilder 结束时调用 build()。否则会失败。
    • 你完全正确。谢谢!用你的发现更新了帖子。
    猜你喜欢
    • 2019-11-10
    • 2021-04-22
    • 2019-06-14
    • 2017-04-13
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 2021-11-14
    • 2015-03-31
    相关资源
    最近更新 更多