Interview preparation--elasticSearch正排索引原理

发布于:2024-07-01 ⋅ 阅读:(13) ⋅ 点赞:(0)
正排索引
  • ElastciSearch 适合做或者说擅长做全文检索,在做全文检索的时候,他会通过生成倒排索引的方式来辅助查询,生成一个词项到 文档id的一个倒排表,这样直接通过 词项可以快速找到所有的 稳定信息。

  • 但是并不是所有的搜索都是全文检索的需求,因此在ElasticSearch中还存在其他的查询方式,例如基础的聚合查询它用到的就是正排索引,底层使用的数据结构就是(doc values)

  • 概念:doc values 本质上是一个序列化的 列式存储 。列式存储 适用于聚合、排序、脚本等操作,所有的数字、地理坐标、日期、IP 和不分词( not_analyzed )字符类型都会默认开启,不支持text和annotated_text类型。

  • 如果在Mapping创建之初我就能确定某一些字段我一定不会参与聚合查询,那么我们应该将整个字段的doc values 设置为false,这样这个字段就不会参与正排索引的创建,以此来减少索引对磁盘空间的占用

正排索引 和 倒排索引的区别
  • 倒排索引:倒排索引的优势是可以快速查找包含某个词项的文档有哪些。如果用倒排来确定哪些文档中是否包含某个词项就很鸡肋。
  • 正排索引:正排索引的优势在于可以快速的查找某个文档里包含哪些词项。同理,正排不适用于查找包含某个词项的文档有哪些。
正排索引数据结构
  • doc values:doc values是正排索引的基本数据结构之一,其存在是为了提升排序和聚合效率,默认true,如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc values值以节省磁盘空间。
  • fielddata:基于内存的一个正排索引,比如我们认为某个字段不需要参与聚合查询,但是我们可以开启fielddata的方式来应对临时查询,elasticsearch在对文档中字段A聚合查询的时候,如果A没有开启doc values,但是开启了fielddata,这个时候他会在内存中给A生成一个正排索引,基于内存的方式去走索引查询,fielddata 的构建和管理发生在 JVM Heap中,Fielddata默认是不启用的,因为text字段比较长,一般只做关键字分词和搜索,很少拿它来进行全文匹配和聚合还有排序。
案例分析正排索引 & 倒排索引
  • 有如下json数据
{"id":"1","name":"xiaomi phone","price":13999,"date":"2024-05-19","tags":["xingjiabi","fashao","buka"]}{"id":"2","name":"hongmi erji","price":4999,"date":"2024-05-20","tags":["xingjiabi","fashao","menjinka"]}{"id":"3","name":"xiaomi erji","price":4999,"date":"2024-05-20","tags":["xingjiabi","fashao","menjinka"]}{"id":"4","name":"hongmi phone","price":4999,"date":"2024-05-20","tags":["xingjiabi","fashao","menjinka"]}{"id":"5","name":"xiaomi nfc erji","price":399,"date":"2024-05-20","tags":["newbee","xuhangniu","zhiliangx"]}
  • 正排索引构建出来的正排表如下:
正排索引:每个doc包含哪些term
doc1:    term1、term2、term3...
doc2:    term1、term2、term3...
doc3:    term1、term2、term3...
doc4:    term1、term2、term3...
doc5:    term1、term2、term3...
.....
  • 倒排索引构建出来的倒排表如下:
倒排索引:哪些doc包含了当前term
xiaomi:    doc1、doc3、doc5...
term2:    doc2、doc3、doc6...
term3:    doc5、doc4、doc2...
term4:    doc1、doc7、doc8...
term5:    doc1、doc6、doc9...
.....
正排索引总结
  • 倒排索引适用于确认 term 在哪些文档中, 正排索引正好相反适用于确认某个文档中存在哪些term
  • 正排索引 和 倒排索引都是在index-time时候 创建,存储位置都是在lucene文件中序列化到磁盘中
  • doc values 使用非jvm heap,对gc友好
  • 不分词的field在index-time的时候会生成正排索引,在做聚合查询的时候使用正排索引,设置了分词的field在index-time的时候没有正排索引,而没有doc values的field需要做聚合查询的唯一方式就是开启fielddata,让es在内存中生成一个临时的正排索引
doc values & fieldData 优化与使用限制
  • 因为filedData会在内存中生成正排索引表,那么会有很多限制
  • doc values优化:fielddata使用的是jvm内存,doc value在内存不足时会静静的待在磁盘中,而当内存充足是,也会蹦到内存里提升性能。
  • fieldData 优化:Fielddata默认是不启用的,因为text字段比较长,一般只做关键字分词和搜索,很少拿它来进行全文匹配和聚合还有排序。
  • ES采用了circuit breaker(熔断)机制避免field data一次性超过物理内存大小而导致内存溢出,如果触发熔断,查询会被终止并返回异常。