ElasticSearch中_recovery_source字段是什么?能否禁用或排除向量?
我在Elasticsearch中创建了两个映射几乎完全相同的索引,唯一区别是其中一个索引的_source配置排除了dense_vector类型的title_vector字段,另一个未做排除:
"mappings": { "_source": {"excludes": ["title_vector"]}, "properties": { ... } }
随后我将1000份相同的文档分别写入这两个索引,索引基本信息如下:
vector_in_source 1000 0 21.5mb 21.5mb no_vector_in_source 1000 0 21.2mb 21.2mb
当我对两个索引执行以下命令查询磁盘占用情况时:
curl --location --request POST 'http://127.0.0.1:9200/index_name/_disk_usage?run_expensive_tasks=true'
发现以下情况:
- 未排除向量的索引按预期在
_source中以普通浮点数形式存储dense_vector; - 排除向量的索引虽未在
_source中存储向量,但生成了一个名为_recovery_source的新字段,其大小恰好等于1000个1024维向量以普通浮点数存储时的占用量。
也就是说,尽管我明确排除了向量在Elasticsearch中的存储,但它们仍被存储在这个新字段中!因此我想了解:
_recovery_source字段是什么?- 能否禁用它?
- 或者至少排除其中的
dense_vector存储?
1. _recovery_source的作用
_recovery_source是Elasticsearch内部用于分片恢复的兜底存储字段。当节点故障重启、分片在集群内重新分配时,Elasticsearch需要原始数据来完整重建分片的索引结构。如果你的索引通过_source.excludes排除了某些字段,而这些字段又是构建索引必需的(比如dense_vector,它会被转化为向量索引结构),Elasticsearch会自动将这些被排除的字段存入_recovery_source,确保分片恢复后能正常提供向量查询等功能。
它是Elasticsearch为保证集群高可用,针对_source排除场景设计的内部机制,不会暴露给用户查询。
2. 能否禁用_recovery_source?
目前没有官方支持的配置项可以完全禁用_recovery_source。它是分片恢复流程的核心组成部分,禁用会导致分片故障后无法重建完整的索引结构,进而丢失相关功能(比如向量查询),因此不建议尝试禁用。
3. 避免dense_vector存入_recovery_source的方案
如果想彻底避免title_vector被存储(包括_source和_recovery_source),需要调整字段的索引策略:
- 设置
store: false并配合_source排除:在映射中给title_vector添加"store": false配置,同时保持_source.excludes。但注意:这种情况下,一旦分片需要恢复,Elasticsearch无法重建该向量字段的索引,会导致向量查询功能失效。仅适用于不需要分片恢复后保留向量功能,或能从外部重新写入向量数据的场景。
示例映射:"mappings": { "_source": {"excludes": ["title_vector"]}, "properties": { "title_vector": { "type": "dense_vector", "dims": 1024, "store": false }, ... } } - 客户端/Ingest Pipeline处理向量生成:如果
title_vector是从其他字段(比如title)生成的,只在写入时传递向量用于构建索引,不将向量字段纳入文档内容。这种方式下,Elasticsearch不会存储向量的原始值,同时也不会在_recovery_source中保留。但后续无法从Elasticsearch中获取原始向量数据,且重新索引时需要重新生成向量。
另外你观察到的两个索引磁盘占用差异极小,是因为_recovery_source的存储格式比_source更紧凑,但本质上仍存储了向量数据。
内容的提问来源于stack exchange,提问作者ruslaniv

