ES 聚合分析不精准原因分析

ElasticSearch 在对海量数据进行聚合分析的时候会损失搜索的精准度来满足实时性的需求。

Terms聚合分析的执行流程:

不精准的原因:

数据分散到多个分片,聚合是每个分片的取 Top X,导致结果不精准。ES 可以不每个分片Top X,而是全量聚合,但势必这会有很大的性能问题。

如何提高聚合精确度

方案1:设置主分片为1

注意7.x版本已经默认为1。

适用场景:数据量小的小集群规模业务场景。

方案2:调大 shard_size 值

设置 shard_size 为比较大的值,官方推荐:size * 1.5 + 10 。shard_size 值越大,结果越趋近于精准聚合结果值。此外,还可以通过 show_term_doc_count_error 参数显示最差情况下的错误值,用于辅助确定 shard_size 大小。

  • size:是聚合结果的返回值,客户期望返回聚合排名前三,size值就是 3。
  • shard_size: 每个分片上聚合的数据条数。shard_size 原则上要大于等于 size

适用场景:数据量大、分片数多的集群业务场景。

使用 kibana 样例数据进行测试

采用索引迁移方式,将数据迁移到 我们自己创建的索引中

复制代码
PUT my_flights
{
  "settings": {
    "number_of_shards": 20
  },
  "mappings" : {
      "properties" : {
        "AvgTicketPrice" : {
          "type" : "float"
        },
        "Cancelled" : {
          "type" : "boolean"
        },
        "Carrier" : {
          "type" : "keyword"
        },
        "Dest" : {
          "type" : "keyword"
        },
        "DestAirportID" : {
          "type" : "keyword"
        },
        "DestCityName" : {
          "type" : "keyword"
        },
        "DestCountry" : {
          "type" : "keyword"
        },
        "DestLocation" : {
          "type" : "geo_point"
        },
        "DestRegion" : {
          "type" : "keyword"
        },
        "DestWeather" : {
          "type" : "keyword"
        },
        "DistanceKilometers" : {
          "type" : "float"
        },
        "DistanceMiles" : {
          "type" : "float"
        },
        "FlightDelay" : {
          "type" : "boolean"
        },
        "FlightDelayMin" : {
          "type" : "integer"
        },
        "FlightDelayType" : {
          "type" : "keyword"
        },
        "FlightNum" : {
          "type" : "keyword"
        },
        "FlightTimeHour" : {
          "type" : "keyword"
        },
        "FlightTimeMin" : {
          "type" : "float"
        },
        "Origin" : {
          "type" : "keyword"
        },
        "OriginAirportID" : {
          "type" : "keyword"
        },
        "OriginCityName" : {
          "type" : "keyword"
        },
        "OriginCountry" : {
          "type" : "keyword"
        },
        "OriginLocation" : {
          "type" : "geo_point"
        },
        "OriginRegion" : {
          "type" : "keyword"
        },
        "OriginWeather" : {
          "type" : "keyword"
        },
        "dayOfWeek" : {
          "type" : "integer"
        },
        "timestamp" : {
          "type" : "date"
        }
      }
    }
}

POST _reindex
{
  "source": {
    "index": "kibana_sample_data_flights"
  },
  "dest": {
    "index": "my_flights"
  }
}

迁移完成后,可以看到有一万多条数据 ,并且分片数量是 20

而源索引的分片数量是 1

然后采用同样的聚合查询:

先看一下默认分片为 1 的源索引:

复制代码
POST /kibana_sample_data_flights/_search
{
  "size": 0, 
  "aggs": {
    "weather": {
      "terms": {
        "field": "OriginWeather",
        "size": 5,
        "show_term_doc_count_error": true
      }
    }
  }
}

这里有个属性说明一下:

show_term_doc_count_error:true

在Terms Aggregation的返回中有两个特殊的数值:

  • doc_count_error_upper_bound : 被遗漏的term 分桶,包含的文档,有可能的最大值
  • sum_other_doc_count: 除了返回结果 bucket 的 terms 以外,其他 terms 的文档总数(总数 - 返回的总数)

然后再看下 我们自己创建的索引 分片为 5 的情况

复制代码
POST /my_flights/_search
{
  "size": 0, 
  "aggs": {
    "weather": {
      "terms": {
        "field": "OriginWeather",
        "size": 5,
        "shard_size": 5, 
        "show_term_doc_count_error": true
      }
    }
  }
}

可以看到此时就有可能被遗漏的文档了,因为我们设置的分片数是 20,此时查询只查询了 5 分片

把分片调大一些再看:

就没有可能被遗漏的数据了,说明调大分片数是可以增加聚合精度的,但是对性能肯定会有一定影响的

适用场景:数据量大、分片数多的集群业务场景。

方案3:将size设置为全量值,来解决精度问题

将size设置为2的32次方减去1也就是分片支持的最大值,来解决精度问题。

原因:1.x版本,size等于 0 代表全部,高版本取消 0 值,所以设置了最大值(大于业务的全量值)。

全量带来的弊端就是:如果分片数据量极大,这样做会耗费巨大的CPU 资源来排序,而且可能会阻塞网络。

适用场景:对聚合精准度要求极高的业务场景,由于性能问题,不推荐使用。

方案4:使用 Clickhouse / Spark 进行精准聚合

适用场景:数据量非常大、聚合精度要求高、响应速度快的业务场景。

感谢观看!!!感兴趣的小伙伴可以关注收藏,持续更新中~~~

相关推荐
福客AI智能客服1 小时前
从被动响应到主动赋能:家具行业客服机器人的革新路径
大数据·人工智能
小五传输3 小时前
隔离网闸的作用是什么?新型网闸如何构筑“数字护城河”?
大数据·运维·安全
jkyy20143 小时前
AI健康医疗开放平台:企业健康业务的“新基建”
大数据·人工智能·科技·健康医疗
蚁巡信息巡查系统3 小时前
政府网站与政务新媒体检查指标抽查通报如何面对
大数据·内容运营
视界先声4 小时前
2025年GEO自动化闭环构建实践:监测工具选型与多平台反馈机制工程分享
大数据·人工智能·自动化
Elasticsearch4 小时前
Elasticsearch:构建一个 AI 驱动的电子邮件钓鱼检测
elasticsearch
百***24374 小时前
GPT5.1 vs Claude-Opus-4.5 全维度对比及快速接入实战
大数据·人工智能·gpt
alan07215 小时前
【Java + Elasticsearch全量 & 增量同步实战】
java·elasticsearch·jenkins
AI营销前沿5 小时前
私域AI首倡者韩剑,原圈科技领航AI营销
大数据·人工智能
Percent_bigdata5 小时前
数据治理平台选型解析:AI大模型与智能体如何重塑企业数字基座
大数据·人工智能