• ElasticSearch 聚合查询百分比


    这里用的是es5.6.9

    bucket_script :它执行一个脚本,该脚本可以对多桶聚合中的指定度量执行每桶计算,指定的度量标准必须为数字,并且脚本必须返回数值。

    官方语法

    https://www.elastic.co/guide/en/elasticsearch/reference/master/search-aggregations-pipeline-bucket-script-aggregation.html

    {
        "bucket_script": {
            "buckets_path": {
                "my_var1": "the_sum", 
                "my_var2": "the_value_count"
            },
            "script": "params.my_var1 / params.my_var2"
        }
    }

    给的一个例子

    算出t-shirts卖出的钱占总钱数的百分比
    POST /sales/_search
    {
        "size": 0,
        "aggs" : {
            "sales_per_month" : {
                "date_histogram" : {
                    "field" : "date",
                    "interval" : "month"
                },
                "aggs": {
                    "total_sales": {
                        "sum": {
                            "field": "price"
                        }
                    },
                    "t-shirts": {
                      "filter": {
                        "term": {
                          "type": "t-shirt"
                        }
                      },
                      "aggs": {
                        "sales": {
                          "sum": {
                            "field": "price"
                          }
                        }
                      }
                    },
                    "t-shirt-percentage": {
                        "bucket_script": {
                            "buckets_path": {
                              "tShirtSales": "t-shirts>sales",
                              "totalSales": "total_sales"
                            },
                            "script": "params.tShirtSales / params.totalSales * 100"
                        }
                    }
                }
            }
        }
    }
    script:聚合运行的脚本
    buckets_path:脚本变量的映射及其与我们希望用于变量的桶的关联路径
    format:格式以应用于此聚合的输出值
    gap_policy:在数据中发现差距时应用的策略
    其中"t-shirts"这个聚合里面又套了一层取值的聚合是因为buckets_path里引用的必须是一个值filter返回的不是一个值

    也可以这样写
    POST /sales/_search
    {
        "size": 0,
        "aggs" : {
            "sales_per_month" : {
                "date_histogram" : {
                    "field" : "date",
                    "interval" : "month"
                },
                "aggs": {
                    "total_sales": {
                        "sum": {
                            "field": "price"
                        }
                    },
                    "t-shirts": {
                      "filter": {
                        "term": {
                          "type": "t-shirt"
                        }
                      }
                    },
                    "t-shirt-percentage": {
                        "bucket_script": {
                            "buckets_path": {
                              "tShirtSales": "t-shirts>_count",
                              "totalSales": "total_sales"
                            },
                            "script": "params.tShirtSales / params.totalSales * 100"
                        }
                    }
                }
            }
        }
    }

    在spring data 中使用 bucket_script 聚合

    ValueCountAggregationBuilder valueCountAggregationBuilder=AggregationBuilders.count("聚合的名字:total_attendance").field("聚合的字段名");
    FilterAggregationBuilder filterLate=AggregationBuilders
                    .filter("聚合的名字:filter_count",QueryBuilders.termQuery("term的字段名","过滤的字段值"));
    Map<String,String> scriptParams=new HashMap<>();
            lateScriptParams.put("total","total_attendance");
            lateScriptParams.put("count","filter_count>_count");
    BucketScriptPipelineAggregationBuilder script= PipelineAggregatorBuilders
                    .bucketScript("聚合的名字:result",scriptParams,new Script("params.count/params.total*100")).format("#.##");

    然后就是把聚合放到查询里面了

    TermsAggregationBuilder usersResultAggs= AggregationBuilders.terms("users_term").field("userId.keyword")
    .subAggregation(result)
    .subAggregation(filter_count)
    .subAggregation(total);

    取值

    1.使用elasticsearchTemplate

    elasticsearchTemplate.query(searchQuery, searchResponse -> {
                Map<String,Aggregation> aggregationMap=searchResponse.getAggregations().asMap();
                StringTerms stringTerms = (StringTerms)aggregationMap.get("取值的那个聚合的名字:users_term");

            //取值
           return aggregationMap.get("取值的那个聚合的名字:result")).getValue()
       stringTerms.getBuckets().forEach(aggs->{
    Map<String,Aggregation> subAggMap=aggs.getAggregations().asMap();
        //取百分比
        Double result=((InternalSimpleValue)subAggMap.get("notsigendScript")).getValue();
      });
      return 返回结果;
    });



  • 相关阅读:
    从0到1构建适配不同端(微信小程序、H5、React-Native 等)的taro + dva应用
    一个基于Ionic3.x cordova的移动APP demo
    基于 MUI 构建一个具有 90 +页面的APP应用
    风清杨之Oracle的安装与说明
    浅析C#中的“==”和Equals
    window.open()的使用
    动态生成级联下拉框和多选框
    生成二维码的两种方式
    登录添加验证码校验
    oracle11g的安装以及配置
  • 原文地址:https://www.cnblogs.com/double-yuan/p/9826522.html
Copyright © 2020-2023  润新知