Su的技术博客

  • 首页
  • 原创
  • 视频
  • Java
  • MySQL
  • DDD
  • 事故复盘
  • 架构方案
  • AI
  • Other
  • 工具
    • AI工具集
    • 工具清单
    • JSON在线格式化
    • JSON在线比较
    • SQL在线格式化
  • 打赏
  • 关于
路很长,又很短
  1. 首页
  2. ElasticSearch
  3. 正文
                           

【ElasticSearch】Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案

2025-03-02 508点热度 0人点赞 0条评论

一、引出问题

在 Elasticsearch 中,我们经常使用 _count 和 _stats API来获取索引的统计信息。

但是,当使用 _count 和 _stats 这两个API时,返回的结果可能会有显著差异,尤其是在处理含有nested字段的文档时。

例如,执行以下查询时,返回的结果分别为:


GET /achieve_base/_count 返回 11163

GET /achieve_base/_stats 返回 300276

Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案

——来自死磕 Elasticsearch 星球微信群

可以看到,_stats 返回的文档数量远大于_count的结果,产生了较大的差异。

Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案

那么,究竟是什么原因导致了这种差异呢?

二、分析问题

Count API与 Stats API 的区别:

根据 Elasticsearch 官方文档,_count和_stats API分别具有不同的功能和统计粒度:

1. _count API

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-count.html

用于查询索引中匹配给定查询的文档数量。

默认情况下,_count 统计的是文档数,而不区分文档的类型。

它对文档的计数是按照文档本身进行的,不会区分是否包含 nested字段。

GET /<target>/_count

2. _stats API

用于获取有关一个或多个索引的统计信息,包括存储大小、文档数量、字段的存储统计等。

它统计的是 Lucene 级别的文档数,包括索引中的所有原始文档和嵌套字段所产生的文档数量。

通过 level 参数可以控制统计的粒度,primaries 返回的是主分片的统计,total则是主分片和副本分片的统计。

默认返回的是索引级别的统计信息。

GET /<target>/_stats

需要注意的是,_stats API 默认统计的是所有 Lucene文档 ,包括由nested字段生成的多个Lucene文档。

三、nested字段对统计结果的影响

当使用nested字段时,每个nested数组的元素会被视为一个独立的文档来存储。

这意味着一个文档中包含多个nested元素时,Elasticsearch会为每个nested元素生成一个Lucene文档,这些文档会被计入到_stats API的统计中。

例如,在以下示例中,文档包含了一个nested_field,其中包含多个嵌套文档:

DELETE test_nested_index
PUT /test_nested_index
{
"mappings": {
    "properties": {
      "nested_field": {
        "type": "nested",
        "properties": {
          "name": { "type": "keyword" }
        }
      }
    }
  }
}

POST /test_nested_index/_doc/1 { "nested_field": [     {"name": "nested_doc1"},     {"name": "nested_doc2"},     {"name": "nested_doc3"}   ] }

 

## 返回结果1 GET /test_nested_index/_count

 

## 返回结果4 GET /test_nested_index/_stats

 

GET /test_nested_index/_search

Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案

执行GET /test_nested_index/_count 返回文档数:1,如下图所示。

Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案

而执行 GET /test_nested_index/_stats 返回文档数:4。

Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案

这个差异就是因为nested字段的每个元素都被存储为独立的Lucene文档(示意图如下图所示)。

Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案

非严谨的示意图

继续写入更多数据后:

POST /test_nested_index/_bulk
{"index":{"_id":"1"}}
{"nested_field":[{"name":"a1"},{"name":"a2"},{"name":"a3"},{"name":"a4"},{"name":"a5"},{"name":"a6"},{"name":"a7"},{"name":"a8"},{"name":"a9"},{"name":"a10"},{"name":"a11"},{"name":"a12"},{"name":"a13"},{"name":"a14"},{"name":"a15"},{"name":"a16"},{"name":"a17"},{"name":"a18"},{"name":"a19"},{"name":"a20"},{"name":"a21"},{"name":"a22"},{"name":"a23"},{"name":"a24"},{"name":"a25"},{"name":"a26"},{"name":"a27"}]}
{"index":{"_id":"2"}}
{"nested_field":[{"name":"b1"},{"name":"b2"},{"name":"b3"},{"name":"b4"},{"name":"b5"},{"name":"b6"},{"name":"b7"},{"name":"b8"},{"name":"b9"},{"name":"b10"},{"name":"b11"},{"name":"b12"},{"name":"b13"},{"name":"b14"},{"name":"b15"},{"name":"b16"},{"name":"b17"},{"name":"b18"},{"name":"b19"},{"name":"b20"},{"name":"b21"},{"name":"b22"},{"name":"b23"},{"name":"b24"},{"name":"b25"},{"name":"b26"},{"name":"b27"}]}

## 返回结果2 GET /test_nested_index/_count   ## 返回结果56 GET /test_nested_index/_stats

 

GET /test_nested_index/_search

Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案

下图执行结果为:27*2+2=56。

Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案

四、解决问题

1. 刷新索引

有时候,数据还没有完全刷新到磁盘或者Lucene索引中,可能会导致_count和_stats之间的差异。

可以通过执行refresh操作来刷新索引,确保统计数据是最新的。

POST /achieve_base/_refresh

然后重新执行GET /achieve_base/_count和GET /achieve_base/_stats,以确认刷新后的数据是否一致。

2. 重新理解nested字段的影响

如前所述,如果文档中使用了nested字段,我们需要理解_stats API返回的是Lucene级别的文档数量,这其中包括了nested字段生成的所有文档。

因此,_count返回的是原始文档的数量,而_stats则返回了原始文档及其nested元素所产生的Lucene文档数量。

3. 数据结构优化

如果nested字段的使用导致了文档数量的显著增加,可以考虑优化数据模型,例如使用flattened类型,或者将嵌套数据存储为独立的文档,而不是在同一个文档中嵌套。

Elasticsearch 字段膨胀不要怕,Flattened 类型解千愁!

五、结论

在Elasticsearch中,_count 和 _stats 两个 API 的统计方式不同,导致它们返回的结果会存在差异。

_count统计的是原始文档数量,而_stats统计的是Lucene文档数量,包括由nested字段生成的文档。

理解这些区别,有助于我们更好地使用Elasticsearch,尤其是在处理复杂数据结构时。

本文仅供学习!所有权归属原作者。侵删!文章来源: 铭毅天下Elasticsearch -铭毅天下 :http://mp.weixin.qq.com/s/8Ux7PDCoP2NMjvV6ikMxqA

更多文章:

  1. 系统设计入门:成为高级软件工程师的指南
  2. Elasticsearch 使用误区之一——将 Elasticsearch 视为关系数据库!
  3. Spring事务无法生效的11个场景
  4. 记一次升级MySQL驱动包引发的事故
  5. Routing Elasticsearch架构VI:路由
  6. Spring中@Autowired和@Inject注解的区别?
  7. Elasticsearch 字段膨胀不要怕,Flattened 类型解千愁!
  8. ElasticSearch之各大版本演进,发布8.0.0 Alpha 2版本
  9. 事件驱动架构(EDA) VS 请求响应架构(RR)
  10. 用图讲解SOLID设计原则
标签: ElasticSearch
最后更新:2025-03-03

coder

分享干货文章,学习先进经验。

打赏 点赞
< 上一篇
下一篇 >
广告
文章目录
  • 一、引出问题
  • 二、分析问题
    • 1. _count API
    • 2. _stats API
  • 三、nested字段对统计结果的影响
  • 四、解决问题
    • 1. 刷新索引
    • 2. 重新理解nested字段的影响
    • 3. 数据结构优化
  • 五、结论
最新 热点 推荐
最新 热点 推荐
干货 | 论Elasticsearch数据建模的重要性 马蜂窝消息总线——面向业务的消息服务设计 基于 MySQL Binlog 实现可配置的异构数据同步 视频笔记:Google发布Agent2Agent协议 视频笔记:什么是微服务,为什么是微服务? 视频笔记:什么是AI 智能体? 视频笔记:什么是Flink? 如何秒级实现接口间“幂等”补偿:一款轻量级仿幂等数据校正处理辅助工具
Elasticsearch 使用误区之六——富文本内容写入前不清洗基于 MySQL Binlog 实现可配置的异构数据同步马蜂窝消息总线——面向业务的消息服务设计干货 | 论Elasticsearch数据建模的重要性你可以不用RxJava,但必须得领悟它的思想!如何秒级实现接口间“幂等”补偿:一款轻量级仿幂等数据校正处理辅助工具视频笔记:什么是Flink?视频笔记:什么是AI 智能体?
干货!有些bug,跨年才有机会见 Elasticsearch基础但非常有用的功能之一:别名 系统设计 | 处理业务公式 6种限流实现,附代码![通俗易懂] 殷浩详解DDD系列 第一讲 - Domain Primitive 记一次网络请求连接超时的事故 RocketMQ消息回溯实践与解析 2023 年 AI 盘点(转译)

CRUD (1) Event Sourcing (1) graphql (1) id (1) NoSQL (1) quarkus (1) rest (1) RocketMQ (2) Spring Boot (1) zk (1) zookeeper (1) 上下文 (1) 事务消息 (1) 二级缓存 (1) 值对象 (1) 关系数据库 (1) 分布式缓存 (1) 原子性 (1) 唯一ID (1) 商品 (1) 多对多 (1) 子域 (1) 字符集 (1) 客户端心跳 (1) 幂等 (2) 干货 (1) 并发 (1) 应用场景 (1) 应用架构图 (1) 康威定律 (2) 异步复制 (1) 微服务架构 (2) 总体方案 (1) 技术方案 (2) 技术架构 (2) 技术架构图 (1) 技能 (1) 持续集成 (1) 支撑域 (1) 故障恢复 (1) 数据架构图 (1) 方案选型 (1) 日记 (1) 服务发现 (1) 服务治理 (1) 服务注册 (2) 机房 (1) 核心域 (1) 泄漏 (1) 洋葱架构 (1) 消息队列 (5) 源码剖析 (1) 灰度发布 (1) 熔断 (1) 生态 (1) 画图工具 (1) 研发团队 (1) 线程 (2) 组织架构 (1) 缓存架构 (1) 编码 (1) 视频 (18) 读写分离 (1) 贵州 (1) 软件设计 (1) 迁移 (1) 通用域 (1) 集群化 (1) 雪花算法 (1) 顺序消息 (1)

推荐链接🔗
  • AI工具集
  • 工具箱🛠️

COPYRIGHT © 2014-2025 verysu.com . ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

粤ICP备15033072号-2

x