ES 8.x的新特性介绍--Doc-values-only search

ES在8.1版本引入了Doc-values-only search,这是个非常实用的功能。具体功能见文档:https://www.elastic.co/guide/en/elasticsearch/reference/8.1/doc-values.html#doc-value-only-fields

ES默认在开启索引的时候,也会加上doc_values。doc_values是针对字段的列式存储。

很多时候,这些字段主要是用来做聚合和排序的一些功能,索引功能几乎不用。但是加上索引本身会增加写入资源开销和存储容量的开销。去掉字段的索引大概能减少>20% 存储空间和提升>20% 构建索引吞吐。

但是去掉了字段索引,就完全无法对字段进行检索。

为了应对这种主要以聚合和排序为主,但是也要能支持检索功能的需求。ES增加了对doc_values类型的检索能力。

这样针对某个字段,可以配置成这样:

     "session_id": { 
       "type":  "long",
       "index": false
     }

这样session_id字段就不包含索引,只使用了doc_values。

但是从使用上,依然能像正常的long类型一样,可以进行term、range等查询。

Doc-values-only search是怎么实现的呢?

下面就以long类型为例:

@Override
public Query termQuery(String field, Object value, boolean isIndexed) {
    if (hasDecimalPart(value)) {
        return Queries.newMatchNoDocsQuery("Value [" + value + "] has a decimal part");
    }
    long v = parse(value, true);
    if (isIndexed) {
        return LongPoint.newExactQuery(field, v);
    } else {
        return SortedNumericDocValuesField.newSlowExactQuery(field, v);
    }
}

在termQuery,如果字段没建索引,就走到了SortedNumericDocValuesField.newSlowExactQuery方法。

接下来的实现在lucene中,long类型使用的是SortedNumericDocValuesRangeQuery,针对term和range,都是使用SortedNumericDocValuesRangeQuery。

SortedNumericDocValuesRangeQuery查找数据的方式也比较简单,就是遍历所有doc,找到range范围内的数据。所以性能是比较差的。

针对这点,ES在针对indexing sort字段上做了优化,增加了IndexSortSortedNumericDocValuesRangeQuery,这个可以按二分查找进行doc过滤。

ES针对Doc-values-only search还能使用更加复杂的查询功能,比如keyword里的prefix、wildcard等。这些是通过Script功能实现的,实现方式就是走了runtime query的方式。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容