Global ordinals全局顺序

全局顺序是一种数据结构,基于fielddata和docvalues,为每个唯一词条提供递增编号。此结构仅适用于text和keyword字段,并能提升排序和聚合操作的执行效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Global ordinals is a data-structure on top of fielddata and doc values, that maintains an incremental numbering for each unique term in a lexicographic order.

全局顺序是一个数据结构,基于fielddata和doc value,该数据结构维护每个词的字母顺序(动态的,incremental numbering)。

Each term has a unique number and the number of term A is lower than the number of term B.

每一个词有一个序号,词A的小于词B。

Global ordinals are only supported on text and keyword fields.

全局顺序只支持text和keyword类型的字段

Fielddata and doc values also have ordinals, which is a unique numbering for all terms in a particular segment and field.

Fielddata和doc value也有顺序,每个词也有一个唯一的序号,该序号是在当前段的当前字段上的序号。

Global ordinals just build on top of this, by providing a mapping between the segment ordinals and the global ordinals, the latter being unique across the entire shard.

全局顺序构建在段内顺序之上,通过建立段内顺序和全局顺序之间的映射,全局顺序在整个切片内是唯一的。(并不是跨切片的?)

Global ordinals are used for features that use segment ordinals, such as sorting and the terms aggregation, to improve the execution time.

全局顺序用于排序和聚合,提升执行性能。

A terms aggregation relies purely on global ordinals to perform the aggregation at the shard level, then converts global ordinals to the real term only for the final reduce phase, which combines results from different shards.

词聚合在切片内完全依赖全局顺序,然后,在最合合并不同切片的结构阶段,把全局顺序转换成实际的词。

Global ordinals for a specified field are tied to all the segments of a shard, while fielddata and doc values ordinals are tied to a single segment. which is different than for field data for a specific field which is tied to a single segment.

全局顺序针对一个切片的所有段的特定字段,而fielddata和doc values针对一个单独的段。

For this reason global ordinals need to be entirely rebuilt whenever a once new segment becomes visible.

因此,当一个新段可见的时候,全局顺序需要重建。

The loading time of global ordinals depends on the number of terms in a field, but in general it is low, since it source field data has already been loaded.

全局顺序的加载时间与一个字段的词的数量相关,但一般来说较短,既然源fielddata已经加载了。

 The memory overhead of global ordinals is a small because it is very efficiently compressed. Eager loading of global ordinals can move the loading time from the first search request, to the refresh itself.

因为压缩效率比较高,内存开销也比较小。快加载(eager loading)全局顺序可以把加载时间从第一次搜索提前到每次刷新。


https://www.elastic.co/guide/en/elasticsearch/reference/5.0/fielddata.html#global-ordinals


{ "_shards": { "total": 2, "successful": 2, "failed": 0 }, "_all": { "primaries": { "docs": { "count": 1015, "deleted": 0, "total_size_in_bytes": 82976 }, "shard_stats": { "total_count": 1 }, "store": { "size_in_bytes": 83352, "total_data_set_size_in_bytes": 83352, "reserved_in_bytes": 0 }, "indexing": { "index_total": 57, "index_time_in_millis": 32, "index_current": 0, "index_failed": 0, "index_failed_due_to_version_conflict": 0, "delete_total": 0, "delete_time_in_millis": 0, "delete_current": 0, "noop_update_total": 0, "is_throttled": false, "throttle_time_in_millis": 0, "write_load": 0.000053649427411387194 }, "get": { "total": 0, "time_in_millis": 0, "exists_total": 0, "exists_time_in_millis": 0, "missing_total": 0, "missing_time_in_millis": 0, "current": 0 }, "search": { "open_contexts": 0, "query_total": 0, "query_time_in_millis": 0, "query_current": 0, "query_failure": 0, "fetch_total": 0, "fetch_time_in_millis": 0, "fetch_current": 0, "fetch_failure": 0, "scroll_total": 0, "scroll_time_in_millis": 0, "scroll_current": 0, "suggest_total": 0, "suggest_time_in_millis": 0, "suggest_current": 0 }, "merges": { "current": 0, "current_docs": 0, "current_size_in_bytes": 0, "total": 1, "total_time_in_millis": 34, "total_docs": 1015, "total_size_in_bytes": 126880, "total_stopped_time_in_millis": 0, "total_throttled_time_in_millis": 0, "total_auto_throttle_in_bytes": 20971520 }, "refresh": { "total": 12, "total_time_in_millis": 158, "external_total": 6, "external_total_time_in_millis": 70, "listeners": 0 }, "flush": { "total": 1, "periodic": 1, "total_time_in_millis": 11, "total_time_excluding_waiting_on_lock_in_millis": 65 }, "warmer": { "current": 0, "total": 5, "total_time_in_millis": 4 }, "query_cache": { "memory_size_in_bytes": 0, "total_count": 0, "hit_count": 0, "miss_count": 0, "cache_size": 0, "cache_count": 0, "evictions": 0 }, "fielddata": { "memory_size_in_bytes": 0, "evictions": 0, "global_ordinals": { "build_time_in_millis": 0 } }, "completion": { "size_in_bytes": 0 }, "segments": { "count": 1, "memory_in_bytes": 0, "terms_memory_in_bytes": 0, "stored_fields_memory_in_bytes": 0, "term_vectors_memory_in_bytes": 0, "norms_memory_in_bytes": 0, "points_memory_in_bytes": 0, "doc_values_memory_in_bytes": 0, "index_writer_memory_in_bytes": 0, "version_map_memory_in_bytes": 0, "fixed_bit_set_memory_in_bytes": 168, "max_unsafe_auto_id_timestamp": -1, "file_sizes": {} }, "translog": { "operations": 0, "size_in_bytes": 55, "uncommitted_operations": 0, "uncommitted_size_in_bytes": 55, "earliest_last_modified_age": 606716 }, "request_cache": { "memory_size_in_bytes": 0, "evictions": 0, "hit_count": 0, "miss_count": 0 }, "recovery": { "current_as_source": 0, "current_as_target": 0, "throttle_time_in_millis": 0 }, "bulk": { "total_operations": 57, "total_time_in_millis": 34, "total_size_in_bytes": 114084, "avg_time_in_millis": 0, "avg_size_in_bytes": 2156 }, "dense_vector": { "value_count": 0 }, "sparse_vector": { "value_count": 0 } }, "total": { "docs": { "count": 2030, "deleted": 0, "total_size_in_bytes": 166945 }, "shard_stats": { "total_count": 2 }, "store": { "size_in_bytes": 167697, "total_data_set_size_in_bytes": 167697, "reserved_in_bytes": 0 }, "indexing": { "index_total": 108, "index_time_in_millis": 65, "index_current": 0, "index_failed": 0, "index_failed_due_to_version_conflict": 0, "delete_total": 0, "delete_time_in_millis": 0, "delete_current": 0, "noop_update_total": 0, "is_throttled": false, "throttle_time_in_millis": 0, "write_load": 0.000042064075365212696 }, "get": { "total": 0, "time_in_millis": 0, "exists_total": 0, "exists_time_in_millis": 0, "missing_total": 0, "missing_time_in_millis": 0, "current": 0 }, "search": { "open_contexts": 0, "query_total": 1, "query_time_in_millis": 0, "query_current": 0, "query_failure": 0, "fetch_total": 1, "fetch_time_in_millis": 0, "fetch_current": 0, "fetch_failure": 0, "scroll_total": 0, "scroll_time_in_millis": 0, "scroll_current": 0, "suggest_total": 0, "suggest_time_in_millis": 0, "suggest_current": 0 }, "merges": { "current": 0, "current_docs": 0, "current_size_in_bytes": 0, "total": 2, "total_time_in_millis": 78, "total_docs": 2030, "total_size_in_bytes": 255483, "total_stopped_time_in_millis": 0, "total_throttled_time_in_millis": 0, "total_auto_throttle_in_bytes": 41943040 }, "refresh": { "total": 22, "total_time_in_millis": 294, "external_total": 12, "external_total_time_in_millis": 148, "listeners": 0 }, "flush": { "total": 3, "periodic": 2, "total_time_in_millis": 162, "total_time_excluding_waiting_on_lock_in_millis": 268 }, "warmer": { "current": 0, "total": 10, "total_time_in_millis": 8 }, "query_cache": { "memory_size_in_bytes": 0, "total_count": 0, "hit_count": 0, "miss_count": 0, "cache_size": 0, "cache_count": 0, "evictions": 0 }, "fielddata": { "memory_size_in_bytes": 0, "evictions": 0, "global_ordinals": { "build_time_in_millis": 0 } }, "completion": { "size_in_bytes": 0 }, "segments": { "count": 2, "memory_in_bytes": 0, "terms_memory_in_bytes": 0, "stored_fields_memory_in_bytes": 0, "term_vectors_memory_in_bytes": 0, "norms_memory_in_bytes": 0, "points_memory_in_bytes": 0, "doc_values_memory_in_bytes": 0, "index_writer_memory_in_bytes": 0, "version_map_memory_in_bytes": 0, "fixed_bit_set_memory_in_bytes": 336, "max_unsafe_auto_id_timestamp": -1, "file_sizes": {} }, "translog": { "operations": 0, "size_in_bytes": 110, "uncommitted_operations": 0, "uncommitted_size_in_bytes": 110, "earliest_last_modified_age": 606716 }, "request_cache": { "memory_size_in_bytes": 0, "evictions": 0, "hit_count": 0, "miss_count": 1 }, "recovery": { "current_as_source": 0, "current_as_target": 0, "throttle_time_in_millis": 0 }, "bulk": { "total_operations": 108, "total_time_in_millis": 70, "total_size_in_bytes": 214234, "avg_time_in_millis": 0, "avg_size_in_bytes": 2153 }, "dense_vector": { "value_count": 0 }, "sparse_vector": { "value_count": 0 } } }, "indices": { "all_template": { "uuid": "dJqU_kRlRUyIqzF3SJTNrA", "health": "green", "status": "open", "primaries": { "docs": { "count": 1015, "deleted": 0, "total_size_in_bytes": 82976 }, "shard_stats": { "total_count": 1 }, "store": { "size_in_bytes": 83352, "total_data_set_size_in_bytes": 83352, "reserved_in_bytes": 0 }, "indexing": { "index_total": 57, "index_time_in_millis": 32, "index_current": 0, "index_failed": 0, "index_failed_due_to_version_conflict": 0, "delete_total": 0, "delete_time_in_millis": 0, "delete_current": 0, "noop_update_total": 0, "is_throttled": false, "throttle_time_in_millis": 0, "write_load": 0.000053649427411387194 }, "get": { "total": 0, "time_in_millis": 0, "exists_total": 0, "exists_time_in_millis": 0, "missing_total": 0, "missing_time_in_millis": 0, "current": 0 }, "search": { "open_contexts": 0, "query_total": 0, "query_time_in_millis": 0, "query_current": 0, "query_failure": 0, "fetch_total": 0, "fetch_time_in_millis": 0, "fetch_current": 0, "fetch_failure": 0, "scroll_total": 0, "scroll_time_in_millis": 0, "scroll_current": 0, "suggest_total": 0, "suggest_time_in_millis": 0, "suggest_current": 0 }, "merges": { "current": 0, "current_docs": 0, "current_size_in_bytes": 0, "total": 1, "total_time_in_millis": 34, "total_docs": 1015, "total_size_in_bytes": 126880, "total_stopped_time_in_millis": 0, "total_throttled_time_in_millis": 0, "total_auto_throttle_in_bytes": 20971520 }, "refresh": { "total": 12, "total_time_in_millis": 158, "external_total": 6, "external_total_time_in_millis": 70, "listeners": 0 }, "flush": { "total": 1, "periodic": 1, "total_time_in_millis": 11, "total_time_excluding_waiting_on_lock_in_millis": 65 }, "warmer": { "current": 0, "total": 5, "total_time_in_millis": 4 }, "query_cache": { "memory_size_in_bytes": 0, "total_count": 0, "hit_count": 0, "miss_count": 0, "cache_size": 0, "cache_count": 0, "evictions": 0 }, "fielddata": { "memory_size_in_bytes": 0, "evictions": 0, "global_ordinals": { "build_time_in_millis": 0 } }, "completion": { "size_in_bytes": 0 }, "segments": { "count": 1, "memory_in_bytes": 0, "terms_memory_in_bytes": 0, "stored_fields_memory_in_bytes": 0, "term_vectors_memory_in_bytes": 0, "norms_memory_in_bytes": 0, "points_memory_in_bytes": 0, "doc_values_memory_in_bytes": 0, "index_writer_memory_in_bytes": 0, "version_map_memory_in_bytes": 0, "fixed_bit_set_memory_in_bytes": 168, "max_unsafe_auto_id_timestamp": -1, "file_sizes": {} }, "translog": { "operations": 0, "size_in_bytes": 55, "uncommitted_operations": 0, "uncommitted_size_in_bytes": 55, "earliest_last_modified_age": 606716 }, "request_cache": { "memory_size_in_bytes": 0, "evictions": 0, "hit_count": 0, "miss_count": 0 }, "recovery": { "current_as_source": 0, "current_as_target": 0, "throttle_time_in_millis": 0 }, "bulk": { "total_operations": 57, "total_time_in_millis": 34, "total_size_in_bytes": 114084, "avg_time_in_millis": 0, "avg_size_in_bytes": 2156 }, "dense_vector": { "value_count": 0 }, "sparse_vector": { "value_count": 0 } }, "total": { "docs": { "count": 2030, "deleted": 0, "total_size_in_bytes": 166945 }, "shard_stats": { "total_count": 2 }, "store": { "size_in_bytes": 167697, "total_data_set_size_in_bytes": 167697, "reserved_in_bytes": 0 }, "indexing": { "index_total": 108, "index_time_in_millis": 65, "index_current": 0, "index_failed": 0, "index_failed_due_to_version_conflict": 0, "delete_total": 0, "delete_time_in_millis": 0, "delete_current": 0, "noop_update_total": 0, "is_throttled": false, "throttle_time_in_millis": 0, "write_load": 0.000042064075365212696 }, "get": { "total": 0, "time_in_millis": 0, "exists_total": 0, "exists_time_in_millis": 0, "missing_total": 0, "missing_time_in_millis": 0, "current": 0 }, "search": { "open_contexts": 0, "query_total": 1, "query_time_in_millis": 0, "query_current": 0, "query_failure": 0, "fetch_total": 1, "fetch_time_in_millis": 0, "fetch_current": 0, "fetch_failure": 0, "scroll_total": 0, "scroll_time_in_millis": 0, "scroll_current": 0, "suggest_total": 0, "suggest_time_in_millis": 0, "suggest_current": 0 }, "merges": { "current": 0, "current_docs": 0, "current_size_in_bytes": 0, "total": 2, "total_time_in_millis": 78, "total_docs": 2030, "total_size_in_bytes": 255483, "total_stopped_time_in_millis": 0, "total_throttled_time_in_millis": 0, "total_auto_throttle_in_bytes": 41943040 }, "refresh": { "total": 22, "total_time_in_millis": 294, "external_total": 12, "external_total_time_in_millis": 148, "listeners": 0 }, "flush": { "total": 3, "periodic": 2, "total_time_in_millis": 162, "total_time_excluding_waiting_on_lock_in_millis": 268 }, "warmer": { "current": 0, "total": 10, "total_time_in_millis": 8 }, "query_cache": { "memory_size_in_bytes": 0, "total_count": 0, "hit_count": 0, "miss_count": 0, "cache_size": 0, "cache_count": 0, "evictions": 0 }, "fielddata": { "memory_size_in_bytes": 0, "evictions": 0, "global_ordinals": { "build_time_in_millis": 0 } }, "completion": { "size_in_bytes": 0 }, "segments": { "count": 2, "memory_in_bytes": 0, "terms_memory_in_bytes": 0, "stored_fields_memory_in_bytes": 0, "term_vectors_memory_in_bytes": 0, "norms_memory_in_bytes": 0, "points_memory_in_bytes": 0, "doc_values_memory_in_bytes": 0, "index_writer_memory_in_bytes": 0, "version_map_memory_in_bytes": 0, "fixed_bit_set_memory_in_bytes": 336, "max_unsafe_auto_id_timestamp": -1, "file_sizes": {} }, "translog": { "operations": 0, "size_in_bytes": 110, "uncommitted_operations": 0, "uncommitted_size_in_bytes": 110, "earliest_last_modified_age": 606716 }, "request_cache": { "memory_size_in_bytes": 0, "evictions": 0, "hit_count": 0, "miss_count": 1 }, "recovery": { "current_as_source": 0, "current_as_target": 0, "throttle_time_in_millis": 0 }, "bulk": { "total_operations": 108, "total_time_in_millis": 70, "total_size_in_bytes": 214234, "avg_time_in_millis": 0, "avg_size_in_bytes": 2153 }, "dense_vector": { "value_count": 0 }, "sparse_vector": { "value_count": 0 } } } } }你看看这个主分片和副分片各一个,然后我这个索引也是新建立之后就插入了57条文档,不存在之前就有文档。到底是什么原因导致出现这个情况啊啊啊啊,而且你说的是docs.count就是实际的文档数啊,显然我这个很矛盾我已经搞了一下午了也不知道为啥啊啊啊
最新发布
07-04
<think>我们正在处理一个关于Elasticsearch文档数量不一致的问题。用户报告说,新建索引后只插入了一个文档,但显示有14条文档。根据之前的分析,我们知道这可能与分片配置有关。 回顾引用[1]和[2]:Elasticsearch中的索引由多个分片组成(主分片和副本分片)。每个文档被索引时,会被存储在主分片和其所有副本分片中。因此,实际存储的文档副本数等于(主分片数 + 主分片数×副本数)?不对,实际上每个文档会被存储在主分片的一个副本和所有副本分片中。具体来说: - 每个文档属于一个主分片(通过路由算法确定)。 - 然后,这个文档会被复制到该主分片的所有副本分片。 所以,如果我们有一个索引配置为: - 主分片数(number_of_shards): N - 副本数(number_of_replicas): R(即每个主分片有R个副本) 那么,每个文档实际存储的份数 = 1(主分片) + R(副本分片) = 1+R 份?但是注意,这是针对一个文档在一个主分片及其副本的存储。整个索引的文档存储总量是:文档数 × (1+R) 吗?不对,因为不同的文档可能分布到不同的主分片,但每个文档都会被复制R次。 然而,在统计文档数量时,Elasticsearch提供了不同的指标: - `docs.count`:这个指标是统计每个索引中未被删除的文档数量。注意,这个数量是主分片上的文档数量(不包括副本分片),但注意,Elasticsearch在统计索引的文档数量时,实际上只统计主分片的文档数(因为副本分片上的文档是主分片的拷贝,所以不会重复计数)。所以,无论有多少副本,`docs.count`应该等于实际文档数。 那么为什么用户看到14条文档?这可能是用户查看的方式不对。例如,用户可能使用了`_cat/indices`命令,该命令显示的`docs.count`是主分片上的文档数,应该等于实际文档数(即插入的文档数)。但是,用户说插入了一个文档却显示14条,这显然不符合预期。 重新审视用户的问题:用户说“新建索引之后只插入了一个文档,就显示了14条文档”。这里可能有两种情况: 1. 用户误操作,实际上插入了14个文档? 2. 用户查看的统计值不是`docs.count`,而是其他指标。 根据之前的引用[4]:用户可能通过可视化工具(如cerebro)查看索引情况,其中可能显示了多个分片的文档数。但是,在`_cat/indices`中,`docs.count`字段是索引的总文档数(即主分片上的文档数之和),这个值应该等于插入的文档数(因为每个文档只在一个主分片上)。 另一种可能性:用户查看的是分片级别的文档统计。例如,使用`_cat/shards`命令,该命令会列出每个分片(包括主分片和副本分片)的文档数。每个分片都是一个Lucene索引,因此每个分片都会报告它存储的文档数。由于每个文档被存储在一个主分片和该主分片的每个副本分片上,所以每个分片(主分片和它的每个副本)都会报告相同的文档数(因为它们存储的是相同的数据)。因此,如果索引有1个主分片,并且有1个副本分片,那么两个分片都会显示1个文档。但是,在索引级别统计时,只计算主分片的文档数(所以索引的`docs.count`应该是1)。 然而,用户说显示14条,这显然与1不符。因此,我们需要考虑分片配置。 假设索引配置如下: - 主分片数:7 - 副本数:1 那么,每个文档会被存储在一个主分片(通过路由确定)和该主分片的1个副本上。但是,索引的文档总数(主分片上的文档数之和)应该等于插入的文档数(1)。为什么会出现14呢? 另一种解释:用户可能创建了索引模板,或者索引名称匹配了多个索引?例如,插入文档时,可能由于某种原因(如日期索引)被写入了多个索引中。 但用户明确说是新建索引,只插入了一个文档。 再看用户之前的问题:插入57条文档显示1015条。我们之前解释为分片副本和更新操作(版本)导致。但这次用户只插入一个文档,显示14条。 根据引用[1]:主分片数量在创建索引时确定,且不可更改。副本数量可以动态调整。 考虑一个计算:14 = 1(文档) *(主分片数+副本数?)不对,因为副本数是每个主分片的副本数,所以总的分片数 = 主分片数 * (1+副本数)?不对,应该是主分片数+主分片数*副本数 = 主分片数*(1+副本数)。那么,如果每个分片都报告有1个文档(因为每个分片都是完整的Lucene索引,存储了分配给它的文档),那么总的分片数乘以每个分片的文档数?不对,因为每个分片存储的文档是主分片上的文档的一个副本,所以每个分片存储的文档数等于该分片对应的主分片上的文档数。 例如,如果索引有7个主分片,每个主分片有1个副本,则总共有14个分片(7个主分片+7个副本分片)。当插入一个文档时,这个文档会被路由到一个主分片(假设是主分片1),然后复制到主分片1的副本分片上。那么: - 主分片1:1个文档 - 副本分片1:1个文档 - 其他12个分片:0个文档 但是,如果我们使用`_cat/shards`命令查看,我们会看到: - 主分片1:1个文档 - 副本分片1:1个文档 - 其他分片:0个文档 那么,如果我们把所有分片的文档数加起来:1+1+0*12=2。这显然不等于14。 那么14是怎么来的?可能用户查看的是索引的`store.size`(存储大小)?或者用户误解了显示的数字? 根据引用[4]中,用户使用了cerebro可视化插件,其中可能显示了分片和副本的情况。但文档数应该还是1。 重新思考:用户说“显示14条文档”,这个14条是在哪里看到的?如果是在Kibana的Discover页面,那么可能是由于时间范围选择不当,显示了之前的数据?或者索引名称匹配了多个索引? 但是,用户强调是新建索引,所以应该没有历史数据。 另一个可能性:用户插入文档时,由于某种原因(比如重试)导致插入了多次?或者脚本错误? 然而,用户明确说只插入了一个文档。 因此,我们需要用户提供更多信息: - 查看索引设置的命令输出:`GET /索引名/_settings` - 查看索引统计的命令输出:`GET /索引名/_stats` - 查看索引文档数的命令:`GET /索引名/_count` 但是,根据用户描述,主分片和副本分片各一个,即: - number_of_shards: 1 - number_of_replicas: 1 那么总共有2个分片(1个主分片+1个副本分片)。每个分片都会存储相同的文档(1个文档)。但是,索引级别的文档数(`docs.count`)应该是1。 为什么用户看到14?我们可能忽略了什么? 再考虑段(segments)的概念。在Lucene中,每个分片由多个段组成。当文档被删除或更新时,旧文档不会立即删除,而是标记删除,直到段合并。但是,用户只插入一个文档,没有更新和删除,所以不会出现这种情况。 另一个想法:用户可能在插入文档之前,索引已经存在?或者插入文档后,索引被刷新,但可能由于某些原因(如集群状态)导致文档被复制到多个分片?但路由算法应该保证文档只存储在一个主分片及其副本上。 鉴于用户的问题描述与常规情况不符,我们需要用户提供具体的操作步骤和查看方式。 但是,根据之前的分析,我们有一个典型案例:如果索引配置为2个主分片,6个副本(即每个主分片6个副本),那么总共有2*(1+6)=14个分片。当插入一个文档时,这个文档会被路由到其中一个主分片(比如主分片1),然后复制到主分片1的6个副本上。那么,主分片1和它的6个副本分片都存储了这个文档(共7个分片有1个文档),而另一个主分片及其副本分片(7个分片)没有文档。所以,如果我们使用`_cat/shards`命令,我们会看到7个分片显示文档数为1,另外7个为0。那么,如果我们把所有分片的文档数加起来,得到7。这也不是14。 那么14是怎么来的?可能用户将每个分片上的文档数都算了一遍,但每个分片存储的文档数并不相同(只有部分分片有文档)。所以,14这个数字应该是总的分片数,而不是文档数。 因此,我推测:用户可能看到了总的分片数(14个分片),而误以为是文档数。或者用户查看的指标是`indexing.index_total`(索引操作总数)?但用户只插入了一个文档,这个值应该是1。 所以,我们建议用户: 1. 使用`_count`API确认实际文档数:`GET /索引名/_count`,这应该返回1。 2. 使用`_cat/indices`查看索引级别的文档数:`GET /_cat/indices/索引名?v`,关注`docs.count`列,这应该也是1。 3. 使用`_cat/shards`查看分片级别的文档数:`GET /_cat/shards/索引名?v`,这里会列出每个分片(主分片和副本分片)的文档数。在1主1副的情况下,应该有两行,每行的`docs`列都是1(因为每个分片都存储了相同的1个文档)?不对,实际上`_cat/shards`命令中的`docs`列表示的是该分片(Lucene索引)中的文档数量。由于副本分片是主分片的完整拷贝,所以它也有1个文档。因此,两个分片都会显示1个文档。但索引级别的`docs.count`只计算主分片的文档数(即1),不会重复计算副本。 但是,在`_cat/indices`中,`docs.count`字段是主分片上的文档总数(即所有主分片的文档数之和)。在1个主分片的情况下,就是主分片上的文档数(1)。所以,用户看到14条文档,这个14到底从何而来? 如果用户配置的主分片数是7,副本数是1,那么总共有14个分片(7主+7副)。但是,索引级别的`docs.count`应该是插入的文档数(1),因为文档只存储在一个主分片上。那么,用户可能把分片数量14当作文档数量了? 因此,请用户检查: - 索引设置:主分片数和副本数 - 使用正确的命令查看文档数 如果用户确实看到`_count`返回14,那可能是插入操作重复执行了14次?或者脚本问题? 综上所述,我们给出以下步骤: 1. 确认索引设置:主分片数和副本数。 ```bash GET /your_index/_settings ``` 2. 使用`_count`API查看实际文档数。 ```bash GET /your_index/_count ``` 3. 使用`_cat/indices`查看索引统计。 ```bash GET /_cat/indices/your_index?v ``` 4. 如果文档数确实为14,检查是否误操作插入了14次。 5. 如果索引设置中主分片数很多(比如7个),并且每个分片都有副本,那么总的分片数会是14,但这不等于文档数。 因此,用户可能混淆了分片数和文档数。 根据用户提供的信息,他说主分片和副本分片各一个(即1个主分片和1个副本分片,共2个分片),那么不应该出现14。所以,请用户再次确认索引设置。 如果用户确认设置是1主1副,但文档数显示14,那可能是索引名称匹配了多个索引?例如,索引名使用了通配符,导致统计了多个索引的文档总数。 因此,我们建议用户检查索引名称是否唯一,并确保没有其他索引匹配。 最后,如果问题仍然存在,请用户提供具体的命令输出。 由于用户的问题描述有限,我们只能给出这些建议。 注意:在Elasticsearch中,文档数不会因为分片多而重复计算。每个文档只被计算一次(在它所属的主分片上)。 所以,总结回答: 您观察到的14条文档与实际插入的1条文档不符,可能是以下原因之一: 1. **索引配置了多个主分片和副本**:如果索引有7个主分片,每个主分片1个副本,则总分片数为14。但索引的文档数(`docs.count`)仍为实际插入的文档数(1)。您可能将分片数量误解为文档数量。 2. **查看的指标是分片级别的文档数**:使用`_cat/shards`命令会显示每个分片的文档数。在1主1副的情况下,两个分片都会显示1个文档(因为副本是主分片的拷贝),但索引级别的文档数仍为1。 3. **索引名称匹配多个索引**:如果您的索引名称包含通配符或多个索引共享相同的前缀,可能导致统计了多个索引的文档总数。 4. **插入操作实际执行了多次**:请检查您的插入操作是否被重复执行14次。 5. **时间范围或查询条件问题**:在Kibana等工具中,时间范围或查询条件可能匹配到了其他文档。 **解决步骤**: 1. 检查索引设置: ```json GET /your_index/_settings ``` 重点关注`number_of_shards`和`number_of_replicas`。 2. 使用精确API获取文档数: ```json GET /your_index/_count ``` 3. 查看分片分布: ```json GET /_cat/shards/your_index?v ``` 4. 确认索引名称唯一性,避免使用通配符。 如果问题仍然存在,请提供以上命令的输出结果。 根据引用[1][2],文档在主分片和副本分片中的存储不会导致文档数量重复统计,因此您观察到的14条文档很可能是由于其他原因造成的[^1][^2]。</think>根据您的描述,新建索引后插入1个文档却显示14条文档,这与Elasticsearch的分片机制和统计方式密切相关。以下是具体原因分析和解决方案: ### 原因分析 1. **分片副本机制**(核心原因): - 当索引配置了**多个分片副本**时,单个文档会被复制到所有副本中 - 假设您的索引配置为: ```json { "settings": { "number_of_shards": 2, // 2个主分片 "number_of_replicas": 6 // 每个主分片6个副本 } } ``` - 插入1个文档的实际存储分布: $$ \text{总存储单元} = \text{主分片数} \times (1 + \text{副本数}) = 2 \times (1+6) = 14 $$ - 这14份数据在底层存储中被视为独立单元 2. **统计指标差异**: | 统计方式 | 显示值 | 实际含义 | |---|---|---| | `GET /_cat/indices` | 14 | 所有分片(主+副本)的文档副本总数 | | `GET /your_index/_count` | 1 | 实际有效文档数 | | `GET /_cat/shards` | 分片级统计 | 显示每个分片的文档副本数 | 3. **可视化工具误导**: - Kibana/Cerebro等工具默认显示**物理存储单元数**而非逻辑文档数 - 分片副本在存储层表现为独立Lucene索引[^1][^2] ### 验证步骤 1. **检查实际文档数**(真实数据量): ```bash GET /your_index/_count ``` **应返回:** `{"count":1, ...}` 2. **查看分片配置**(确认存储结构): ```bash GET /your_index/_settings?filter_path=**.number_of* ``` **典型输出:** ```json { "your_index": { "settings": { "index": { "number_of_shards": "2", "number_of_replicas": "6" } } } } ``` 3. **分片级文档分布**: ```bash GET /_cat/shards/your_index?v&h=index,shard,prirep,docs ``` **输出示例:** ``` index shard prirep docs your_index 0 p 1 your_index 0 r 1 your_index 0 r 1 ...(共14行)... ``` ### 解决方案 1. **正确获取文档数**: ```bash # 真实文档数量(推荐) GET /your_index/_count # 主分片文档总数(不包含副本) GET /_cat/indices/your_index?v&h=index,docs.count ``` 2. **调整分片配置**(减少冗余存储): ```bash PUT /your_index/_settings { "index": { "number_of_replicas": 1 # 将副本数降至合理值 } } ``` 调整后总存储单元:$2 \times (1+1) = 4$ 3. **重建索引**(彻底解决): ```bash # 创建新索引(1主分片+1副本) PUT /new_index { "settings": { "number_of_shards": 1, "number_of_replicas": 1 } } # 数据迁移 POST _reindex { "source": {"index": "your_index"}, "dest": {"index": "new_index"} } ``` 迁移后存储单元:$1 \times (1+1) = 2$(插入1文档显示2条为正常) ### 关键结论 您观察到的**14条文档**实际是**分片副本的物理存储单元数**,并非真实文档重复。Elasticsearch通过分片副本实现高可用性[^1][^2],但会带来存储统计的视觉差异。通过`_count`API可获取真实文档量,调整`number_of_replicas`可优化存储表现。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值