【拓展篇】Elasticsearch 6.0 一个索引只允许有一个type

一,单index,单type
未来发布的elasticsearch 6.0.0版本为保持兼容,仍然会支持单index,多type结构,但是作者已不推荐这么设置。在elasticsearch 7.0.0版本必须使用单index,单type,多type结构则会完全移除。 针对这一问题,elasticsearch 作者的讨论:https://github.com/elastic/ela ... 24317https://www.elastic.co/guide/e ... .html  二,单index,多type结构弊端
人们经常会谈到index类似传统sql数据库的“database”,而type类似于"table"。现在想想,这是一个非常糟糕的比喻,而这个比喻会造成很多错误的假设。
在传统的sql数据库中,各个"table"之间是互相独立的,在一个表中的列都与另一个表相同名称的列无关。
①,而在我们elasticsearch中同一 Index 下,同名 Field 类型必须相同,即使不同的 Type;
②, 同一 Index 下,TypeA 的 Field 会占用 TypeB 的资源(互相消耗资源),会形成一种稀疏存储的情况。尤其是 doc value ,为什么这么说呢?doc value为了性能考虑会保留一部分的磁盘空间,这意味着 TypeB 可能不需要这个字段的 doc_value 而 TypeA 需要,那么 TypeB 就被白白占用了一部分没有半点用处的资源;
③,Score 评分机制是 index-wide 的,不同的type之间评分也会造成干扰。
④,索引元数据本身是放在主节点中维护的,CP 设计。意味着涉及到大量字段变更及元数据变更的操作,都会导致该 Index 被堵塞或假死。我们应该对这样的 Index 做隔离,避免影响到其他 Index 正常的增删改查。甚至当涉及到字段变更十分频繁且无法预定义 schema 的场景时,是否要使用 ES 都应该慎思熟虑了!
 
三,doc value 扩展介绍
 
参见官方文档docvalues 先看倒排索引组织结构大致如下:
 

es 多个type 联合 es type类型_字段

 
如果我要查询包含 brown 的文档有哪些?这个就是全文检索了,也相当好办,先从词典里遍历到 brown 这个单词,然后根据倒排索引查得 Doc_1 和 Doc_2 包含这个单词。
如果我要查 Doc_1 和 Doc_2 包含的单词分别有什么?这个用倒排索引的话开销会非常大,至少是要将整张表关于 Doc_1 和 Doc_2 的列数据遍历一遍才行。这时候我们将数据换一种组织形式,将会起到非常好的效果。
 

es 多个type 联合 es type类型_elasticsearch_02

Doc_1 和 Doc_2 存了什么单词,一目了然。我们把这种数据的组织方式叫做doc_value。
倒排索引的特点很明显,就是为了全文检索而生的,但是对于一些聚合查询(排序、求平均值等等)的场景来说,显然不适用。那么这样一来我们为了应对一些聚合场景就需要结构化数据来应付,这里说的结构化数据就是『列存储』,也就是上面说的doc_value。
doc_value在 ES 中有几个应用场景:
 
对某个字段排序;
某个字段聚合查询( max/min/count );
部分过滤器 ( 地理位置过滤器 );
某个字段的脚本执行。等等。
 
doc_value是顺序存储到磁盘的,因此访问是很快的。当我们所处理的集合小于所给的 JVM 堆内存,那么整个数据集合是会被加载到内存里的;如果数据集合大于所给的堆内存,那么就会分页加载到内存之中,而不会报出『OutOfMemory Error』。
 
值得一提的是,doc_value的字段使用极其频繁,因此在5.x 版本后强化成为两个字段,分别是 text 和 keyword。
text:string 类型,支持倒排索引,不支持 doc_value;
keyword:string 类型,不支持倒排索引,支持doc_value。
 
四:参考
①:ElasticSearch 内部机制浅析