抛砖引玉:我们先来思考一个问题,es中的 agg 桶聚类,等操作是如何来做到的?
如果想要提升聚类的性能,又应该如何做呢?
我们可以从 es的底层存储原理中来寻找答案!所以将会学到 Doc Values这个列式存储的数据结构。
那又为什么需要列式存储? 我提一个需求你大概就能明白了:如果mysql中数据有1000W,如果让你去执行group by操作,需要多长的时间呢? 假如数据有 1 亿、10亿,又需要花多长时间呢?如果能做到秒级别? 因为mysql是按行来存储数据的,想要完成这个操作,就得一条一条数据读出来,然后再去计算分组。而列存就不一样了。只需要读出来我们需要 group by的字段即可。
那么doc value究竟是什么呢?
在 Elasticsearch 中,Doc Values 就是一种列式存储结构,默认情况下每个字段的 Doc Values 都是激活的(除了 text 类型),Doc Values 是在索引时创建的,当字段索引时,Elasticsearch 为了能够快速检索,会把字段的值加入倒排索引中,同时它也会存储该字段的 Doc Values。
区别于倒排索引的定义,Doc Values 被定义为:“正排索引”。
仍然 以 1.2 文档为例,Doc Values 结构如下所示(仅做举例):
Doc | Terms |
---|---|
Doc_1 | brown, dog, fox, jumped, lazy, over, quick, the |
Doc_2 | brown, dogs, foxes, in, lazy, leap, over, quick, summer |
Doc values 通过转置两者间的关系来解决适用倒排索引聚合效率低、难以扩展的问题。
对比可以看出:倒排索引将词项映射到包含它们的文档,doc values 将文档映射到它们包含的词项。
Elasticsearch 中的 Doc Values 常被应用到以下场景:
注意:
因为文档值被序列化到磁盘,我们可以依靠操作系统的帮助来快速访问。
对于不需要:排序、聚合、脚本计算、地理位置过滤的业务场景,可以考虑禁用:Doc Values,以节约存储。
PUT my_index { "mappings": { "properties": { "title": { "type": "keyword", "doc_values": false } } } }