IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> ES 聚合后去重 精度丢失问题方案 -> 正文阅读

[大数据]ES 聚合后去重 精度丢失问题方案

背景:

  • 统计对某个字段去重后的聚合数据

  • 实现类似 sql:select count(distinct fault_name) from wangqi group by fault_name;

问题: 使用 es 的 cardinality 做数据去重 会导致 结果出现 +-%5误差;

Query:
{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "rpt_dt": {
              "gte": "2022-01-01",
              "lt": "2022-12-13"
            }
          }
        }
      ]
  },
  "aggs": {
    "01": {
      "filter": {
        "terms": {
          "data_sources": [
            "01"
          ]
        }
      },
      "aggs": {
        "01": {
          "cardinality": {
            "field": "mac_id"
          }
        }
      }
    }
  }
}

Return:
{
    "01" : {
      "doc_count" : 10901762,
      "01" : {
        "value" : 1425288
      }
    }
}

?方案一:

  • 使用composite 多列聚合 类似 mysql?select count(commissionamount) from xxx_table group by timeperiod,orgId
Query:
{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "rpt_dt": {
              "gte": "2022-01-01",
              "lt": "2022-12-13"
            }
          }
        }
      ]
    }},
  "aggs": {
    "NAME": {
      "composite": {
        "sources": [
          {
            "fault_name": {
             "terms": {
               "field": "mac_id"
             }
            }
          },
          {
            "mac_id":{
              "terms": {
                "field": "fault_name"
              }
            }
          }
        ]
      }
    }
  }
}

Return:
{
  "key" : {
    "fault_name" : "***",
    "mac_id" : "***"
  },
  "doc_count" : 2
}
  • 通过after key 循环查询 所有返回的 fault_name 和 mac_id 排列组合,在python 中进行数量排名,去重数量计算。
  • 优点:
    • 聚合+去重结果 准确
  • 问题:
    • 需要循环查询多次(取决于排列组合数量),代码需要大量改动

方案二:

  • 使用 stats_bucket
扩大es terms 聚合size 上限
PUT test/_settings
{
  "persistent": {
    "search.max_buckets": 2000000
  }
}
GET test/_search?filter_path=aggregations.**.count,aggregations.mac_id.buckets.key,aggregations.mac_id.buckets.key_as_string
{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "rpt_dt": {
              "gte": "2022-06-01",
              "lt": "2022-06-04"
            }
          }
        }
      ]
    }
  },
  "size": 0,
  "aggs": {
    "mac_id": {
        "terms": {
          "field": "rpt_dt",
          "size": 20
        },
        "aggs": {
            "fault_name": {
                "terms": {
                    "field": "mac_id",
                    "size": 100000000
                  }
            },
            "count": {
                "stats_bucket": {
                    "buckets_path": "fault_name._count"
                  }
            }
        }
    }
  }
}

具体介绍:Stats Bucket Aggregation - elasticsearch中文文档??

  • 二级聚合拿到所有二级的桶,使用 stats_bucket 统计所有桶的数量即为 去重后的数量;

  • 优点:

    • 聚合+去重结果 准确,不需要循环查询,代码改动量少
  • 问题:

    • 二级聚合拿到所有桶,比较耗时,查询时间为原始方案的 5-6倍

方案三:

使用 scripted_metric 实现自定义聚合

init_script 定义
map_script 操作 判断
combine_script 操作返回记录
reduce_script 返回sum值

Query:
{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "rpt_dt": {
              "gte": "2022-06-01",
              "lt": "2022-06-04"
            }
          }
        }
      ]
    }
  },
  "size": 0,
  "aggs": {
    "mac_id": {
      "terms": {
        "field": "fault_name",
        "size": 10
      }, 
      "aggs": {
        "spu": {
          "scripted_metric": {
            "init_script": {
              "source": "state.numas=new HashMap();",
              "lang": "painless"
            },
            "map_script": {
              "source": """
              if(doc.mac_id.length>=1){
                String houseKey = doc.mac_id.value;
                state.numas.put(houseKey,1);
              }
              """,
              "lang": "painless"
            },
            "combine_script": {
              "source": """
              double item_finish_count=0;
              for(key in state.numas.keySet()){
                item_finish_count+=1;
              }
              return item_finish_count;""",
              "lang": "painless"
            },
            "reduce_script": {
              "source": """double result=0;
               for(e in states){
                if(!Objects.isNull(e)){
                    result+=e;
                }
              }
              return result;""",
              "lang": "painless"
            },
            "params": {
              "close_sum_key": "close_sum3",
              "house_sum_key": "house_sum3"
            }
          }
        }
      }
    }
  }
}

Return:
{
    "key_as_string" : "2022-06-01 00:00:00",
    "key" : 1654041600000,
    "doc_count" : 274282,
    "spu" : {
        "value" : 268144.0
    }
}
  • es 支持 scripted_metric 使用java 语法脚本的方式 自定义聚合

  • 这里使用 hashmap 数据结构,对第一层 桶做遍历,将 需要去重的字段 放入hashmap ,最后统计hashmap的key数量,得到去重后数量

  • 优点:

    • 聚合去重结果准确,代码改动少
    • 速度快,几乎和原始方案差别不到 慢20%不到
  • 缺点

    • 多分片时脚本较为复杂,因为每个分片有一个hashmap,需要汇总统计,单分片可解决
    • 天量数据可能会占用较大内存,2-3年内数据问题不大

?

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-06-21 21:28:50  更:2022-06-21 21:30:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 21:51:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码