Elasticsreach--Doc Values 和FieldData应用

1.    Doc Values :

Elasticsearch中,倒排索引能够快速查找包含某项的文档,但是对于聚合排序的操作并不高效。Doc Values它将所有单字段存储在单数列中,可以使聚合更快、更高效并且内存友好。

Doc Values是一种列式存储结构,在索引创建时与倒排索引同时生成,都是基于Segment生成并不变的,并序列化到磁盘。常被应用到以下场景:对字段进行排序或者聚合操作,某些过滤以及字段相关的脚本计算。

对于以下倒排索引:

Elasticsreach--Doc Values 和FieldData应用

通过以下查询体得到包含brown的文档的词的完整列表:

Elasticsreach--Doc Values 和FieldData应用

  查询部分:

倒排索引在词表中迅速找到brown,然后,扫描所有列找出包含brown的文档,简单高效的定位到Doc_1  Doc_2 包含 brown 这个 token

  聚合部分:

用倒排索引做这件事情代价很高:我们会迭代索引里的每个词项并收集 Doc_1  Doc_2 列里面 token。这很慢而且难以扩展:随着词项和文档的数量增加,执行时间也会增加。

Doc Values通过转置两者之间的关系来解决这个问题。倒排索引将词项映射到包含它们的文档,doc values将文档映射到包含它们的项:

Elasticsreach--Doc Values 和FieldData应用

通过转置后,再收集到Doc_1 Doc_2 的唯一token变得非常容易。获取每个文档的行,获取所有的词项,然后求并集。搜索使用倒排索引查找文档,聚合操作收集和聚合doc values里的数据。

Doc Values默认对所有字段(所有的数字、地理坐标、日期、IP 和不分析(not_analyzed )字符类型)启用,除了 analyzedstrings。如果某些字段不需要进行聚合,排序或者使用脚本的操作,可以禁用特定字段的 Doc Values,达到节省磁盘空间。

禁用 Doc Values 

Elasticsreach--Doc Values 和FieldData应用

在创建字段映射mappin时,通过设置 doc_values:false ,这个字段将不能被用于聚合、排序以及脚本操作

反过来,让一个字段可以被聚合,通过禁用倒排索引,使它不能被正常搜索:

Elasticsreach--Doc Values 和FieldData应用

2.    Fielddata

Doc values 不支持 analyzed 字符串字段,因为它们不能很有效的表示多值字符串,对于分析的字符串聚合操作需要使用fielddata 的数据结构。与doc values 不同,fielddata 构建和管理 100% 在内存中,常驻于 JVM 内存堆。一旦分析字符串被加载到 fielddata ,他们会一直在那里,直到被驱逐(或者节点崩溃)。

doc values 不同,fielddata延迟加载,它不会在索引时创建。相反,是在查询运行时,动态填充。如果结果中 fielddata 大小超过了指定 大小 ,其他的值将会被回收从而获得空间。默认情况下,设置都是 unbounded Elasticsearch 永远都不会从 fielddata 中回收数据。

为了防止发生这样的事情,可以通过在 config/elasticsearch.yml 文件中增加配置为 fielddata 设置一个上限:

(a) indices.fielddata.cache.size:20% 控制为 fielddata 分配的堆空间大小。有了这个设置,最久未使用(LRU)的 fielddata 会被回收为新数据腾出空间。

(b) indices.fielddata.cache.expire这个参数已经被弃用

因此,在聚合字符串字段之前,请评估情况:

  是否是一个not_analyzed 字段,如果是,可以通过 doc values 节省内存 

  否则,这是一个 analyzed 字段,它将使用 fielddata 并加载到内存中。

若文章有误,欢迎指出!