ElasticSearch 7中创建索引时类型被弃用的原因解析
我明白你为啥会觉得类型有用——把相似文档分组,感觉应该能让搜索更快,但其实ES团队弃用类型,恰恰是因为类型不仅没带来你预想的好处,反而埋下了不少坑,咱们一步步说清楚:
首先得澄清一个关键误解:类型并没有真正帮你加快搜索速度。你以为相似文档分组后搜索更高效,但实际上在ES底层,同一个索引下的不同类型文档是存在同一个Lucene分片里的,类型只是给文档加了一个_type字段做标记,搜索时本质是多了一层过滤条件,反而可能增加额外的开销,完全达不到你预想的“分组提速”效果。
真正让ES团队下决心弃用类型的核心原因有这几个:
字段映射冲突的噩梦
不同类型下的同名字段,很容易出现映射不一致的情况。比如你在blog类型里把author设成了text类型,在comment类型里又把author设成了keyword类型——这时候ES底层的Lucene会把这两个不同类型的字段值存在同一个字段名下,导致搜索结果混乱,甚至直接报错。这种冲突排查起来特别麻烦,尤其是团队协作的时候,很容易有人不小心搞混。设计逻辑的本质混淆
早期ES引入类型是为了模仿关系型数据库的“表”,但ES本质是文档型数据库,这种模仿从根上就有问题。关系型数据库的表是独立存储的,但ES的类型是共享同一个索引的分片和资源,这就导致很多用户误以为类型和表一样独立,结果踩了很多存储和性能的坑。性能和维护的额外负担
类型的存在让索引的映射管理变得复杂,ES需要处理同一索引下不同类型的映射,增加了内部的处理逻辑。而且随着数据量增大,这种共享存储的方式会让分片的压力更大,反而不如把不同类型的数据放在独立索引里,能更好地利用分片的水平扩展能力,性能反而更优。
那替代方案是什么呢?ES官方推荐两种方式:
- 用独立索引存储不同类型的数据:比如之前的
my_index/blog和my_index/comment,改成blog_index和comment_index,这样完全隔离,映射不会冲突,性能也更好。 - 在文档中添加自定义字段区分类型:如果实在不想建多个索引,可以给每个文档加一个比如
doc_type的字段,搜索时用这个字段过滤,效果和之前的类型一样,但避免了类型带来的各种问题。
内容的提问来源于stack exchange,提问作者Aditya

