ES高频面试问题:一张图带你读懂 Elasticsearch 中“正排索引(正向索引)”和“倒排索引(反向索引)”区别

这篇具有很好参考价值的文章主要介绍了ES高频面试问题:一张图带你读懂 Elasticsearch 中“正排索引(正向索引)”和“倒排索引(反向索引)”区别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、正排索引和倒排索引

1.1 正排索引

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

1.2 倒排&正排

  • 倒排:即词项=>包含当前词项的doc_id的列表的映射。倒排索引的优势是可以快速查找包含某个词项的文档有哪些。如果用倒排来确定哪些文档中是否包含某个词项就很鸡肋。
  • 正排:即doc_id=>当前文档包含的所有词项的映射。正排索引的优势在于可以快速的查找某个文档里包含哪些词项。同理,正排不适用于查找包含某个词项的文档有哪些。

2、一张图看懂正排&倒排

2.1 图解

ES高频面试问题:一张图带你读懂 Elasticsearch 中“正排索引(正向索引)”和“倒排索引(反向索引)”区别

2.2 区别

  • 倒排索引的优势 在于查找包含某个项的文档,即用于搜索查询;相反,正排索引的优势是确定哪些项是否存在单个文档里。

  • 倒排索引和正排索引均是在 index-time 时创建,保存在 Lucene 文件中(序列化到磁盘)。

  • doc value 使用非 jvm 内存,gc友好。

  • 不分词的 field 会在 index-time 时生成正排索引,聚合时直接使用正排索引,而分词的field在创建索引时是没有正排索引的,如果没有创建doc value的字段需要做聚合查询,name需要将fielddata打开,设置为true。

3、一个通俗易懂的比喻

举个通俗易懂的例子

有二十个学生报名学习辅导班,每个学生可以报多个班 每个班都有一个班主任

正排索引:相当于班主任,也就是 班主任知道TA所在班级有多少学生

倒排索引:相当于学生,每个学生知道自己都报了哪些班
ES高频面试问题:一张图带你读懂 Elasticsearch 中“正排索引(正向索引)”和“倒排索引(反向索引)”区别
现在我们要查询音乐辅导班美术辅导班包含了哪些学生,问班主任问两次就行,如果我们问学生,就要每个学生都问一遍,问他你是否报了音乐和美术辅导班,如果你不问到最后一个学生,你永远不知道你没有问到的学生 是不是在音乐班和美术班里,也就没办法统计音乐或者美术班的总人数,所以必须问完每个学生,相当于全表扫描。这就是为什么倒排不适合做聚合。

在这个例子里,班主任相当于正排索引,每个doc就是一个班级,每个doc中包含若干词项,每个词项就好比是一个学生。
班主任知道每个班级有哪些学生 也就是每个doc包含哪些词项。学生只知道自己属于哪些班,相当于哪些班级(doc)包含了这个词项。

4、正排索引的数据结构

4.1 doc values

doc values 是正排索引的基本数据结构之一,其存在是为了提升排序和聚合效率,默认true,如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc values值以节省磁盘空间。

4.2 fielddata:

概念:查询时内存数据结构,在首次用当前字段聚合、排序或者在脚本中使用时,需要字段为fielddata数据结构,并且创建倒排索引保存到堆中。与 doc value 不同,当没有doc value的字段需要聚合时,需要打开fielddata,然后临时在内存中建立正排索引,fielddata 的构建和管理发生在 JVM Heap中。Fielddata默认是不启用的,因为text字段比较长,一般只做关键字分词和搜索,很少拿它来进行全文匹配和聚合还有排序。

语法:

PUT /<index>/_mapping
{
  "properties": {
    "tags": {
      "type": "text",
      "fielddata": true  //true:开启fielddata;		false:关闭fielddata
    }
  }
}

独家深层解读: doc values 是文档到词项的映射 inverted 是词项到文档id的映射从原理上讲 先说倒排索引为什么不适合聚合,你无法通过倒排索引确定doc的总数量,并且因为倒排索引默认会执行analysis,即使聚合,结果也可能不准确,所以你还要创建not_analyzed字段,徒增磁盘占用,举个最简单的例子:假如有一张商品表,每个商品都有若干标签,我们执行了以下查询

GET product/_search
{
  "query": {
    "match": {
      "tags": "性价比"
    }
  },
  "aggs": {
    "tag_terms": {
      "terms": {
        "field": "tags.keyword"
      }
    }
  }
}

这段聚合查询的意思 查询包含“性价比”这个标签商品的所有标签,在执行agg的时候 我们使用倒排索引,那么语义将是这样的:在倒排索引中扫描逐个term,看看这个term对用的倒排表中对应的doc的标签 是否包含“性价比”,如果包含,则记录,由于我们不确定下面一个term是否符合条件,所以我们就要一个一个的判断,所以就造成了扫表。如果使用正排索引,而正排索引的指的是,doc中包含了哪些词项,也就是当前doc_id=>当前字段所包含的所有词项的映射,我们要查找的是符合条件的doc中所有的标签,那么我们直接根据key(doc_id)去拿values(all terms)就可以了,所以就不用扫表。所以聚合查询使用正排索引效率高本质是两种数据结构的区别 和结不结合倒排索引没有关系,结合倒排索引只是预先进行了数据筛选。以上是正排索引在原理上对聚合查询友好的原因 下面我说一下关于两种数据结构在数据压缩上的不同,doc values是一种序列化的列式存储结构,其values其中也包含了词频数据。而这种结构是非常有利于数据压缩的,参考第二版VIP课程中的FOR和RBM压缩算法,因为Lucene底层读取文件的方式是基于mmap的,原理是上是从磁盘读取到OS cache里面进行解码的,使用正排索引的数据结构,由于其列式存储的数据和posting list一样可以被高效压缩,所以这种方式极大的增加了从磁盘中读取的速度,因为体积小了,然后把数据在OS Cache中进行解码

5、总结

  • 与 doc value 不同,当没有doc value的字段需要聚合时,需要打开 fielddata,然后临时在内存中建立正排索引,fielddata 的构建和管理发生在 JVM Heap中。

  • Fielddata 默认是不启用的,因为 text 字段比较长,一般只做关键字分词和搜索,很少拿它来进行全文匹配和聚合还有排序。

  • ES 采用了 Circuit Breaker(熔断)机制避免 field data 一次性超过物理内存大小而导致内存溢出,如果触发熔断,查询会被终止并返回异常。

  • fielddata 使用的是 jvm 内存,doc value 在内存不足时会静静的待在磁盘中,而当内存充足时,会蹦到内存里提升性能。文章来源地址https://www.toymoban.com/news/detail-431905.html

到了这里,关于ES高频面试问题:一张图带你读懂 Elasticsearch 中“正排索引(正向索引)”和“倒排索引(反向索引)”区别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一张流程图带你学会SpringBoot结合JWT实现登录功能

    🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:SpringBoot实战 JWT(JsonWebToken)是 一种轻量级的跨域身份验证解决方案 。通常被用于无状态身份验证机制,将用户信息签名

    2024年02月11日
    浏览(65)
  • Elasticsearch 高频面试题(含答案)

    16、Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法? 17、对于 GC 方面,在使用 Elasticsearch 时要注意什么? 18、Elasticsearch 对于大数据量(上亿量级)的聚合如何实现? 19、在并发情况下,Elasticsearch 如果保证读写一致? 20、如何监控 Elasticsearch 集群状态? 21、介绍下你们

    2024年04月11日
    浏览(28)
  • 一张图带你学会入门级别的SpringBoot实现文件上传、下载功能

    🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:SpringBoot实战 标题 一文带你学会使用SpringBoot+Avue实现短信通知功能(含重要文件代码) 一张思维导图带你学会Springboot创

    2024年02月12日
    浏览(59)
  • 一张思维导图带你学会Springboot创建全局异常、自定义异常

    🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:SpringBoot实战 在开发中,都离不开自定义异常、全局处理异常的使用。比如说在一些网站中看到的系统异常,请联系管

    2024年02月14日
    浏览(35)
  • 【Servlet篇】一文带你读懂Request对象

    你问我青春还剩几年?我的回答是,趁现在,正当时。身边朋友都在问我怎样学好一门编程语言,怎样学好Java?怎样通过 Java 找到一份满意的工作?推荐学习此专栏:Java编程基础教程系列(零基础小白搬砖逆袭) 最近一直在更新 Servlet 的文章,在前面一篇中说到 sev

    2024年01月20日
    浏览(33)
  • 【无标题】chatGPT--白话文教你读懂chatGPT

    ChatGPT是Chat(聊天) Generative(生成) Pre-trained(预先训练过的) Transformer(改革者)的一个简写(或称缩写),也有人说Transformer是转换者的意思,但是大致意思基本一样,我们也不用太执着到底是什么意思。本次ChatGPT是美国OpenAI (OpenAI,在美国成立的人工智能研究公司,核心宗旨在于“实

    2023年04月24日
    浏览(39)
  • 一张思维导图带你学会SpringBoot使用AOP实现日志管理功能

    🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:SpringBoot实战 标题 一文带你学会使用SpringBoot+Avue实现短信通知功能(含重要文件代码) 一张思维导图带你学会Springboot创

    2024年02月13日
    浏览(39)
  • 一张思维导图带你学会使用SpringBoot中的Schedule定时发送邮件

    🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:SpringBoot实战 标题 一文带你学会使用SpringBoot+Avue实现短信通知功能(含重要文件代码) 一张思维导图带你学会Springboot创

    2024年02月14日
    浏览(69)
  • 一张思维导图带你学会使用SpringBoot异步任务实现下单校验库存

    🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:SpringBoot实战 标题 一文带你学会使用SpringBoot+Avue实现短信通知功能(含重要文件代码) 一张思维导图带你学会Springboot创

    2024年02月13日
    浏览(28)
  • 一张思维导图带你打通SpringBoot自定义拦截器的思路

    🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:SpringBoot实战 在开发中,都离不开拦截器的使用。比如说在开发登录功能时,采用JWT登录时通过对token进行验证实现登

    2024年02月14日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包