首页 > 其他分享 >ES相关面试题

ES相关面试题

时间:2024-07-10 13:41:11浏览次数:13  
标签:面试题 文档 倒排 全文索引 索引 搜索 相关 词项 ES

题目:

  1. 全文搜索对应的是什么功能,怎么构建索引,查询的时候怎么查

  2. 怎么构建倒排索引,使用MySQL可以实现倒排索引的功能吗

前情提要:

我的项目中的商城项目中存在使用ElasticSearch的情况,所以特地弄了此篇来应对提问,以及还有一个爬虫项目中也使用到了

question One

全文搜索对应的是什么功能,怎么构建索引,查询的时候怎么查?

全文搜索对应的是商品的搜索功能,以及厂家的搜索功能
构建索引这方面其实使用的是ElasticSearch的倒排索引

其中主要涉及的是mappings的构建吧,印象中较为深刻的是构建的时候,首先我们是基于MySQL的数据结构进行构建,其中选取需要在搜索时,商品方面使用到的信息例如说商品的名称,商品的标签,价格等等,而厂家方面使用到的有厂家名字,以及厂家的描述

其中mappings的创建中,需要注意的是keyword,以及text等
区别在于如果是keyword,那么只能精准匹配(不会进行分词),如果是text则会进行分词,在上述的情况上商品名称我使用的是text,而标签使用的是keyword,而对应的厂家名称使用的是多字段将字段同时定义为 keywordtext 类型,以便支持精确匹配和部分匹配
然后值得一提的是,倒排索引嘛,肯定是需要分词的,而我们中文不能像英文那么直接根据空格进行分词,所以我们ES在使用的时候需要额外使用插件IK分词器,然后其他的倒是没太多需要注意的了
在对应的mappings的创建中注意动静分离,只在ES中存储要检索的、修改不频繁的字段

然后就是同步上会有一些额外的考虑,例如说如何保持数据一致?
这里我是在几种方案中做出了选择:

  1. 定时任务(例如说一分钟内进行一次,那么可能会导致说给db增加 负担而且相较于cannal,相当于中间加了一层,而且多涉及了两次IO)
  2. 双写(双写可能会导致数据的增添会延长响应时间,然后双写在使用上还有一个问题就是如果mysql写入成功,而es写入失败的情况,到时候无论是采用重试机制还是说结合定时任务来再次同步或者使用日志告警等机制,都可能处理上会更加麻烦)
  3. 使用Logstash进行数据同步(查询了一些网上的情况,发现是一般需要配合kafka和beats采集器,觉得会让这个项目过于庞大,所以否决了)
  4. 使用Canal进行监听 BinLog来实时同步(最终采用的是Binlog的机制)

然后最后值得一提的是ES几乎提供了许多我们搜索上需要的功能:无论是搜索高亮还是搜索建议上

查询的时候,几乎就是编写他对应的语句喽,其中如果学习的话,编写sql语句也能执行,不过没有原生支持的性能好(具体不太清楚,好像是在官方文档看到的),然后就是其中语句编写的麻烦,我总共试过两个版本一个8开头的版本(在当时应该是仅此最新版的版本)(相对而言踩得坑非常多),另一个是使用7.9,其中maven依赖上都变化了很多,但是之后发现他们的api其实是有共性的甚至可以说他们的api就是基于语句的嵌套来编写的, 之后就容易很多了

Question two

怎么构建倒排索引,使用MySQL可以实现倒排索引的功能吗?

倒排索引(Inverted Index)是一种索引数据结构,常用于全文检索系统和搜索引擎中。它将文档中的内容和文档本身进行关联,便于快速查找包含特定词汇的文档。

倒排索引的基本概念

  1. 文档(Document):要被搜索的基本单位,比如一篇文章、一页网页等。
  2. 词汇表(Vocabulary):文档集合中所有唯一词汇的列表。
  3. 倒排列表(Posting List):每个词汇对应的文档ID列表,表示哪些文档中包含这个词汇。

倒排索引的结构

假设有以下三个文档:

  • Doc1: "The quick brown fox"
  • Doc2: "The quick blue fox"
  • Doc3: "The lazy dog"

倒排索引可能会是这样:

Term Posting List
The Doc1, Doc2, Doc3
quick Doc1, Doc2
brown Doc1
fox Doc1, Doc2
blue Doc2
lazy Doc3
dog Doc3

倒排索引的构建步骤

  1. 词项提取:从每个文档中提取词汇。(例如说中文中需要涉及的IK分词器)
  2. 词项标准化:将词项进行标准化处理,如大小写转换、词干提取等。
  3. 创建词汇表:构建所有词项的词汇表。
  4. 创建倒排列表:将词项与包含该词项的文档ID进行关联。

倒排索引的优点

  • 查询效率高:可以快速定位包含查询词的所有文档。
  • 空间利用率高:相较于其他索引方法,倒排索引的存储需求较少。

使用场景

  • 搜索引擎:如Google、Elasticsearch等。
  • 全文检索系统:用于大规模文本数据的快速搜索和分析。
  • 数据库系统:用于文本字段的高效检索。
使用MySQL可以实现倒排索引的功能吗?

MySQL有个同样能实现相关全文搜索功能的索引,也就是全文索引

其中底层不少就用到了倒排索引的功能,我们也可以自己实现,毕竟MySQL底层应该也是同样的对于中文的分词同样会有问题

MySQL 中的全文索引(Full-Text Index)用于对文本数据进行高效的全文搜索。全文索引允许你在表的一个或多个文本列上创建索引,从而加快包含大量文本数据的列的搜索速度。它主要用于在大文本字段中查找特定的单词或短语,而不是简单的前缀匹配或完整匹配。

全文索引的作用
  1. 高效全文搜索:全文索引使得对大文本数据的搜索更加高效,尤其是在搜索单词或短语时。使用全文索引的搜索速度比对大文本字段进行 LIKE 搜索要快得多。
  2. 自然语言搜索:支持自然语言搜索,允许按相关性对结果进行排序。
  3. 布尔模式搜索:支持布尔模式搜索,可以使用布尔运算符(如 AND, OR, NOT)来构造复杂的查询。
底层数据结构

在 MySQL 中,全文索引的底层数据结构依赖于存储引擎:

MyISAM 存储引擎

MyISAM 使用倒排索引(Inverted Index)来实现全文搜索。倒排索引类似于一个字典,词汇映射到文档 ID 列表,允许快速查找包含特定词汇的所有文档。

InnoDB 存储引擎

InnoDB 的全文索引实现更加复杂,因为 InnoDB 的底层数据结构是 B+ 树,而不是 MyISAM 的倒排索引。为了支持全文搜索,InnoDB 使用了一种特殊的数据结构和处理方法。

  • 分词:首先将文本数据分成词项(terms)。
  • 倒排索引表:创建一个内部的倒排索引表,将词项映射到文档 ID 列表中。
  • 辅助表:使用辅助表存储元数据和其他必要的信息,以支持高效的全文搜索。

具体实现上,InnoDB 可能会使用一种类似于倒排索引的数据结构来存储词项和文档 ID 的关系,同时利用 InnoDB 本身的事务和并发处理能力,确保全文索引的性能和可靠性。

全文索引与 B+ 树的区别
  • B+ 树:主要用于存储和索引有序数据,适合范围查询和排序。每个节点包含一个有序的键值列表,叶节点存储数据的实际指针。
  • 倒排索引:主要用于文本搜索,适合查找包含特定词汇的文档。倒排索引包含词汇到文档 ID 的映射,允许快速查找包含特定词汇的所有文档。
InnoDB 中的全文索引

为了支持全文索引,InnoDB 做了以下调整:

  1. 分词处理:在插入或更新时,对文本进行分词,将其拆分为单独的词项。
  2. 倒排索引:为每个词项创建一个倒排索引,存储词项和文档 ID 的映射。
  3. 辅助数据结构:使用辅助表和数据结构,存储必要的元数据和统计信息,以支持高效查询和排序。

自己的题目:既然Mysql有倒排索引为什么你还要使用ES呢?

题目来源

盒马 暑期实习 Java 一面凉经_牛客网 (nowcoder.com)

标签:面试题,文档,倒排,全文索引,索引,搜索,相关,词项,ES
From: https://www.cnblogs.com/seamount3/p/18293902

相关文章

  • 使用引用 XML 文件来优化 EtherCAT ESI 文件的描述
    使用引用XML文件来优化EtherCATESI文件的描述在EtherCAT系统中,ESI(EtherCATSlaveInformation)文件是描述EtherCAT从设备属性和行为的重要文件。随着系统复杂度的增加,ESI文件的内容可能会变得非常庞大和冗余。为了优化这些文件,我们可以通过引用其他XML文件......
  • Linux使用tcpdump命令抓包并使用wireshark分析常见的场景和解读
    使用tcpdump抓包并使用Wireshark分析网络流量是一项重要的网络管理和故障排除技能。以下是一个简单的步骤指南,涵盖了从抓包到分析的常见场景。抓包安装tcpdump在大多数Linux发行版上,您可以使用包管理器安装tcpdump。例如,在基于Debian的系统上:sudoapt-getin......
  • 蓝队初级常见面试题目
    内网模块内网渗透思路(1)目标:对目标服务器所在的内网资源进行渗透最终获取域控制权限的过程(域控制权限可以控制内网中所有的用户和设备);管理员以一台主机作为域控制器,将内网中其余主机加入到域控当中,那么这台域控制器就可以控制其余的所有主机;所以内网的渗透最终目的就是拿下与控制......
  • CSE 13S LRC Rules of the Game
    Assignment 1LRCCSE 13S, Winter 20241 IntroductionWe are going to simulate a simplified version of the dice game Left, Right, and Center. This game isentirely a game of chance, with no skill or player decisions (except f......
  • HIVE面试题
    HIVE优化:场景1.分组聚合groupby导致数据倾斜--map端聚合:aggr=true会在mapper端先groupby一次,最后再把结果merge起来,为了减少reducer处理的数据量指令:Sethive.groupby.mapaggr.checkinterval=1000000Sethive.map.aggr=truesethive.groupby.skewindata=true;......
  • TypeScript的类型谓词与控制流分析
    目录ts封装类型判断的问题类型谓词TypeScript的“控制流分析”ts封装类型判断的问题在union.d.ts中全局声明一个DataTypedeclaretypeDataType=|"RegExp"|"Object"|"Array"|"Function"|"String"|"Boolean"|"......
  • Qt实现字符验证码相关功能
            本文主要介绍了Qt实现自定义验证码控件的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值。        验证码的原理基于人类视觉和计算机视觉的差异性。通过给用户显示一些难以被机器识别的图形或文字,让用户进行人机交......
  • 《基于 LatentFactor + Redis + ES 实现动态药房分配方法》
    ......
  • Codeforces Round 954(Div. 3)
    CodeforcesRound954(Div.3)目录CodeforcesRound954(Div.3)\(C\).UpdateQueries\(D\).MathematicalProblem\(E\).BeautifulArray方法一:贪心+滑动窗口方法二:DP\(C\).UpdateQueries对索引数组\(ind\)去重排序对字符串\(c\)排序顺序遍历索引数组,将\(s[ind[i]......
  • 如何在 Rust 中安全地处理 Openresty中的字符串?
    HelloWorldRust以简洁高效安全而闻名,那么我们怎么集成到C的项目中呢。尤其是字符串数据结构,该如何正确地交互。借此机会整理一下工作中遇到的难题,希望可以帮助大家走出坑。我们先回顾一下C中字符串的结构。在C语言中,字符是一个连续的内存地址空间以\0结尾。C语言的......