ElasticSearch,简称ES(后文将直接使用这一简称),是一款卓越的开源分布式搜索引擎。其独特之处在于其近乎实时的数据检索能力,为用户提供了迅速、高效的信息查询体验。
它能够解决全文检索,模糊查询、数据分析等问题。那么它的搜索原理是什么呢?
1. 正排索引
正排索引(Forward Index)是一种索引机制,它按照文档的顺序来组织数据,通常是按照文档ID或者其他唯一的标识符进行排序。在正排索引中,索引的键是文档的标识符,而索引的值则是文档的详细信息。
当你知道一个文档的ID时,可以通过正排索引迅速找到该文档的全部信息。
主键ID | 数据 |
1 | 蔡徐坤偶像练习生 |
2 | 蔡徐坤喜欢篮球 |
3 | 蔡徐坤喜欢rap |
4 | 蔡徐坤喜欢唱歌 |
表中记录文档中每个字的位置信息,查找时扫描表中每个文档中字的信息直到找出所有包含查询关键字的文档.
假设使用正向索引,那么当你搜索 ‘rap’ 的时候,搜索引擎必须检索文档中的每一个关键词,假设一个文档中包含成千上百个关键词,可想而知,会造成大量的资源浪费。于是倒排索引应运而生。
2. 倒排索引
倒排索引,也被称为反向索引或逆向索引,是一种索引数据的方法。与正排索引不同。倒排索引是按照文档中的词汇(关键词)来组织。也就是说在倒排索引中,索引的键是文档集合中出现过的每个独特词汇或关键词,索引的值是包含该关键词的所有文档的标识符(如文档ID),以及可选的额外信息。
索引关键字 | 对应数据序号(主键id) |
偶像练习生 | 1 |
喜欢 | 2、3、4 |
蔡徐坤 | 1、2、3、4 |
rap | 3 |
唱歌 | 4 |
篮球 | 2 |
2.1. 倒排索引的组成
ES 倒排索引包含两个部分:单词词典和倒排列表
2.1.1. 单词词典
词典是倒排索引的核心部分,它存储了文档集合中的所有词项(Term)。
词典的主要作用是:
- 提供查询入口,指向与该词项相关的文档列表。
- 支持词项的快速查找,例如通过哈希表或 B+ 树。
2.1.2. 倒排列表
倒排列表是倒排索引的主体部分,每个词项对应一个倒排列表,记录了该词项出现在的文档及位置信息 。
倒排列表的组成
- 文档ID(Doc ID):
- 表示词项所在的文档。
- 通常按照升序存储,便于快速合并查询。
- 词频(Term Frequency, TF):
- 表示词项在文档中出现的次数。
- 用于相关性计算,例如 BM25 算法中用来衡量词项的重要性。
- 位置列表(Position List):
- 记录 词项在文档中的位置(偏移量)。
- 支持短语查询、邻近查询等复杂搜索功能。
3. 分词器
根据前面学习的倒排索引的概念。倒排索引是按照文档中的词汇(关键词)来组织的,索引的键是文档集合中出现过的每个独特词汇或关键词。那es是怎么将这些关键词提取出来的呢?这其实就是es中的分词器在起着作用,它负责将文本切分成一个个有意义的词语,以建立索引或进行搜索和分析。
我们的业务中通常使用的是中文分词,es的中文分词默认会将中文词每个字看成一个词比如:“我想在周五去看电影”会被分为”我”,”想””在”,”周”,”五””,”去”,“看”,“电”,“影”。这显然是不太符合用户的使用习惯,所以我们需要安装中文分词器ik,来讲中文内容分解成更加符合用户使用的关键学。
GET _analyze
{
"text":"我想在周五去看电影"
}
3.1. ik分词器
IK分词器是一个轻量级的中文分词工具,广泛应用于搜索引擎(如Elasticsearch)等领域。IK分词器提供两种分词模式:细粒度模式和智能模式,具有较高的准确性和性能。
- 细粒度模式:每个词都尽可能细化,即按字拆分。
- 智能模式:根据语义进行分词,尽可能合并成合理的词汇。
3.2. ik分词器安装
步骤一:下载
Releases · infinilabs/analysis-ik · GitHub
我学习过程中安装的ES是8.5.3,理应需要下载和ES版本对应的ik分词器,但是官网中,并未给出8.5.3的版本。这里只能下载8.5.2的版本,但是也是可以使用的,后面配置的时候,修改一下配置文件即可。
步骤2:挂载
下载完成后将其压随后放置在:es容器内/usr/share/elasticsearch/plugins目录下,也可以通过配置
挂载目录的方式将插件放在挂载目录下。
将整个“elasticsearch-analysis-ik-8.5.2”文件夹都放在启动es时候指定的挂载目录下。
docker run -d --name oj-es-dev -e "ES_JAVA_OPTS=-Xms256m -Xmx256m" -e "discovery.type=single-node" -v D:\javacode\oj-byte\deploy\dev\elasticSearch\es-plugins:/usr/share/elasticsearch/plugins -e "xpack.security.enabled=false" --privileged --network oj-network -p 9200:9200 -p 9300:9300 elasticsearch:8.5.3
这是我的启动命令,因此我就放在我的本地的 D:\javacode\oj-byte\deploy\dev\elasticSearch\es-plugins 文件下面。
步骤3:修改版本号
还需要将plugin-descriptor.properties里面的版本号进行修改。
然后重启ES的docker容器,进入kibana-dev,确认分词器是否安装成功。
GET _cat/plugins
3.3. 分词模式效果演示
ik分词器提供了两种分词模式:ik_smart 和ik_max_word,其中 ik_smart 模式会尽量保持长词,尽可能地保留词语的完整性,提高搜索的准确性,而ik_max_word 模式则会尽可能多地切分出词汇。即,
- 细粒度模式(ik_max_word):每个词都尽可能细化,即按字拆分。
- 智能模式(ik_smart ):根据语义进行分词,尽可能合并成合理的词汇。
ik_max_word
此时的划分,会比较细粒度,每个词都尽可能细化。
ik_smart