一、问题现象:同一个索引文档数为何不同
统计文档数量有两种方式,一个是count
API,另一个是stats
API。
此处拿测试索引来举例。
bash
## 查询商品索引文档数
GET /test_index/_count --> 返回 33535
{
"count": 33535,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
}
}
GET /test_index/_stats/docs --> 显示 "docs": { "count": 150639 }
{
.....
"total": {
"docs": {
"count": 150639,
"deleted": 866
}
}
两个 API返回的结果竟然不同,是 bug 吗?
二、count与_stats的本质区别
2.1 _count
_count
统计给定查询的文档数量。
_count
只统计主文档,不统计嵌套类型的子文档。
2.2 _stats
_stats
统计所有的 Lucene 文档,包括主文档和 nested 类型的所有子文档。
通过 level 可以控制统计层级,参数【cluster/indices/shards】控制统计层级(集群/索引/分片)。
默认返回的是 indices 级别。
bash
GET /test_nested/_stats/docs?level=indices
GET /test_nested/_stats/docs
三、示例演示
3.1、创建一个包含nested 类型的索引
json
PUT /test_nested
{
"mappings": {
"properties": {
"user": {
"type": "nested", // 定义 nested 类型字段
"properties": {
"name": { "type": "keyword" }
}
}
}
}
}
3.2、插入一个文档,包含两个nested类型的子文档
json
POST /test_nested/_doc/1
{
"user": [
{ "name": "zuiyujava" }, // nested 子文档1
{ "name": "zuiyupython" } // nested 子文档2
]
}
3.3、使用count API 查看
bash
GET /test_nested/_count
返回
{
"count": 1,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
}
}
3.4、使用stats API查看
json
GET /test_nested/_stats/docs
返回
{
"test_nested": {
"uuid": "AiQv1B75SImtSjLPO-hlvA",
"health": "yellow",
"status": "open",
"primaries": {
"docs": {
"count": 3,
"deleted": 0
}
},
"total": {
"docs": {
"count": 3, // 主文档1 + nested子文档2 = 3
"deleted": 0
}
}
}
四、解决
首先是使用refresh
刷新索引,防止数据还没有完全刷新到磁盘或者Lucene索引中。 其次是理解_count
与_stats
的区别,如果是因为nested 嵌套字段引起的文档数量不一致,可以考虑使用flattened
类型。
五、总结
_count
用于查询索引中匹配给定查询的文档数量。
_stats
统计的是 Lucene
级别的文档数,包括索引中的所有原始文档和嵌套字段所产生的文档数量。 明确区分_count
与_stats
的使用场景,避免在_count中滥用通配符查询。
Elasticsearch的文档数不是简单的数字,而是分布式系统复杂性的缩影。理解其内在机制,方能避免被表象迷惑。
(本文实验数据基于Elasticsearch 8.11版本,部分命令需调整后兼容老版本)
最后补充一下API的使用
_count
获取与查询匹配的文档数量。
查询可以通过使用简单的查询字符串作为参数来提供,也可以通过在请求正文中定义查询 DSL 来提供。查询参数是可选的。如果未提供查询参数,API 将用于
match_all
统计所有文档。
_count
API 支持多目标语法。可以跨多个数据流和索引运行单个计数 API 搜索。该操作会在所有分片上广播。对于每个分片 ID 组,都会选择一个副本并针对该副本运行搜索。也就是说可以使用副本提高计数的可扩展性。
所需要的权限:
read
。参考官网地址:www.elastic.co/docs/api/do...
_stats
返回索引统计信息。
对于数据流,API 会检索流的支持索引的统计信息。
所需要的权限:
monitor
参考官网地址:www.elastic.co/docs/api/do...
公众号:醉鱼Java如果这篇文章对您有所帮助或者启发,帮忙点个关注叭,您的支持是我坚持写作的最大动力。
求一键三连:点赞、收藏、关注。
谢谢支持哟 ( ^__^ )。