zoukankan      html  css  js  c++  java
  • composite多桶聚合总结

    简介composite
    composite是一个多桶聚合,它从不同的源创建复合桶,与其他多桶聚合不同,复合聚合可用于高效地对多级聚合中的所有桶进行分页。这种聚合提供了一种方法来流特定聚合的所有桶,类似于滚动对文档所做的操作。
    组合桶是由为每个文档提取/创建的值的组合构建的,每个组合被视为组合桶。如下为官方给的例子:

    {
        "keyword": ["foo", "bar"],
        "number": [23, 65, 76]
    }

    如果我们同时对keyword和number两个字段进行聚合会得出以下的结果:

    { "keyword": "foo", "number": 23 }
    { "keyword": "foo", "number": 65 }
    { "keyword": "foo", "number": 76 }
    { "keyword": "bar", "number": 23 }
    { "keyword": "bar", "number": 65 }
    { "keyword": "bar", "number": 76 }

    看到上面的例子是不是恍然大悟, 就像类似sql中的多group by 多字段,可以对多个字段进行聚合,这非常适用于对于多维度出报表的需求,我这里建议使用的版本为6.5+,因为6.5版本以下此功能还处于测试阶段,设计和代码没有正式的GA功能成熟,并且没有担保。当然我这里也会提供6.5版本以下如何进行多聚合字段的使用。
    首先上官方文档地址:
    https://www.elastic.co/guide/en/elasticsearch/reference/6.5/search-aggregations-bucket-composite-aggregation.html
    其实官方文档已经把该功能说得很详细,如果你只是单纯写DSL实现的话看官方文档就可以,我接下来就介绍如何调用他的javaAPI来使用,当然如果阅读源码能力强的话也可以直接看官方在github的test,地址如下:
    https://github.com/elastic/elasticsearch/tree/master/server/src/test/java/org/elasticsearch/search/aggregations/bucket/composite

    从以上响应的json数组中我们不难看出,该聚合聚合出来的数据是和数据库聚合出来的数据是一致的,所以 composite是可以使用在多字段聚合上的。论证完可行性,我们接下来使用java来实现,实话说这一块我是看源代码才会使用的,网上资料基本为0,而且官方java使用文档里也没用,的确是与遇到了不少坑,写出来方便以后使用能快速回忆。

    package com.springboot.elasticsearch.study.springbootelasticsearch;
    
    import lombok.extern.slf4j.Slf4j;
    import org.elasticsearch.action.search.SearchRequest;
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.search.aggregations.Aggregations;
    import org.elasticsearch.search.aggregations.bucket.composite.*;
    import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.sort.SortOrder;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import javax.annotation.Resource;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @Author: guodong
     * @Date: 2021/9/6 16:43
     * @Version: 1.0
     * @Description:
     */
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @Slf4j
    public class CompositeTest {
    
        @Resource
        private RestHighLevelClient client ;
    
    
        @Test
        public void testCompositeAggregationBuilder01() throws Exception{
            SearchRequest searchRequest = new SearchRequest("items");
            searchRequest.types("item");
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.size(0);
    
            List<CompositeValuesSourceBuilder<?>> sources = new ArrayList<>();
    
            DateHistogramValuesSourceBuilder sendtime = new DateHistogramValuesSourceBuilder("birthDay")
                    .field("birthDay")
                    .dateHistogramInterval(DateHistogramInterval.DAY)
                    .format("yyyy-MM-dd").order(SortOrder.DESC).missingBucket(false);
            sources.add(sendtime);
    
            TermsValuesSourceBuilder userid = new TermsValuesSourceBuilder("title").field("title.text").missingBucket(true);
            sources.add(userid);
    
            TermsValuesSourceBuilder dttype = new TermsValuesSourceBuilder("category").field("category.keyword").missingBucket(true);
            sources.add(dttype);
    
            CompositeAggregationBuilder composite = new CompositeAggregationBuilder("my_buckets", sources);
            composite.size(1000);
            /*********************执行查询******************************/
            searchSourceBuilder.aggregation(composite);
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
    
            /********************取出数据*******************/
            Aggregations aggregations = searchResponse.getAggregations();
            ParsedComposite parsedComposite = aggregations.get("my_buckets");
            List<ParsedComposite.ParsedBucket> list =  parsedComposite.getBuckets();
            Map<String,Object> data = new HashMap<>();
            for(ParsedComposite.ParsedBucket parsedBucket:list){
                data.clear();
                for (Map.Entry<String, Object> m :  parsedBucket.getKey().entrySet()) {
                    data.put(m.getKey(),m.getValue());
                }
                data.put("count",parsedBucket.getDocCount());
                System.out.println(data);
            }
        }
    
    
    }

    数据正确,方法可用,其实这个方法是RestHighLevelClient替我们封装了composite生成DSL。这里注意一下missingBucket的设置,这个的意思是如果该字段没值,为true的时候会返回null,为false不返回整条数据,注意这里是整条数据,而不是单单这个字段而已。

    参考博客:
    https://blog.csdn.net/neweastsun/article/details/108225541
    https://blog.csdn.net/qq_18895659/article/details/86540548

    郭慕荣博客园
  • 相关阅读:
    Beginning Auto Layout Tutorial in iOS 7: Part 2
    Beginning Auto Layout Tutorial in iOS 7: Part 1
    Autolayout 03
    Autolayout 02
    Autolayout 01
    Start Developing iOS Apps Today
    Spring 7大功能模块的作用
    struts2入门
    myeclipse导入工程 Some projects cannot be imported because they already exist in the workspace
    第十一章 Servlet MVC模式
  • 原文地址:https://www.cnblogs.com/jelly12345/p/15237509.html
Copyright © 2011-2022 走看看