掌握它才说明你真正懂 Elasticsearch - Lucene (一)

news/2024/11/29 12:47:44/

Lucene 简介
Lucene 是一种高性能、可伸缩的信息搜索(IR)库,在 2000 年开源,最初由鼎鼎大名的 Doug Cutting 开发,是基于 Java 实现的高性能的开源项目。

Lucene 采用了基于倒排表的设计原理,可以非常高效地实现文本查找,在底层采用了分段的存储模式,使它在读写时几乎完全避免了锁的出现,大大提升了读写性能。

核心模块
Lucene 的写流程和读流程如下图所示:

其中,虚线箭头(a、b、c、d)表示写索引的主要过程,实线箭头(1-9)表示查询的主要过程。

Lucene 中的主要模块及模块说明如下:

analysis:主要负责词法分析及语言处理,也就是我们常说的分词,通过该模块可最终形成存储或者搜索的最小单元 Term。

index 模块:主要负责索引的创建工作。

store 模块:主要负责索引的读写,主要是对文件的一些操作,其主要目的是抽象出和平台文件系统无关的存储。

queryParser 模块:主要负责语法分析,把我们的查询语句生成 Lucene 底层可以识别的条件。

search 模块:主要负责对索引的搜索工作。

similarity 模块:主要负责相关性打分和排序的实现

核心术语
下面介绍 Lucene 中的核心术语:

Term:是索引里最小的存储和查询单元,对于英文来说一般是指一个单词,对于中文来说一般是指一个分词后的词。

词典(Term Dictionary,也叫作字典):是 Term 的集合。词典的数据结构可以有很多种,每种都有自己的优缺点。

比如:排序数组通过二分查找来检索数据:HashMap(哈希表)比排序数组的检索速度更快,但是会浪费存储空间。

FST (finite-state transducer) 有更高的数据压缩率和查询效率,因为词典是常驻内存的,而 FST 有很好的压缩率,所以 FST 在 Lucene 的最新版本中有非常多的使用场景,也是默认的词典数据结构。

倒排序(Posting List):一篇文章通常由多个词组成,倒排表记录的是某个词在哪些文章中出现过。

正向信息:原始的文档信息,可以用来做排序、聚合、展示等。

段(Segment):索引中最小的独立存储单元。一个索引文件由一个或者多个段组成。在 Luence 中的段有不变性,也就是说段一旦生成,在其上只能有读操作,不能有写操作。

Lucene 的底层存储格式如下图所示,由词典和倒排序两部分组成,其中的词典就是 Term 的集合:


词典中的 Term 指向的文档链表的集合,叫做倒排表。词典和倒排表是 Lucene 中很重要的两种数据结构,是实现快速检索的重要基石。

词典和倒排表是分两部分存储的,在倒排序中不但存储了文档编号,还存储了词频等信息。

在上图所示的词典部分包含三个词条(Term):Elasticsearch、Lucene 和 Solr。词典数据是查询的入口,所以这部分数据是以 FST 的形式存储在内存中的。

在倒排表中,“Lucene” 指向有序链表 3,7,15,30,35,67,表示字符串 “Lucene” 在文档编号为 3、7、15、30、35、67 的文章中出现过,Elasticsearch 和 Solr 同理。
检索方式

在 Lucene 的查询过程中的主要检索方式有以下四种:

①单个词查询
指对一个 Term 进行查询。比如,若要查找包含字符串 “Lucene” 的文档,则只需在词典中找到 Term “Lucene”,再获得在倒排表中对应的文档链表即可。

②AND
指对多个集合求交集。比如,若要查找既包含字符串 “Lucene” 又包含字符串 “Solr” 的文档,则查找步骤如下:

在词典中找到 Term “Lucene”,得到 “Lucene” 对应的文档链表。

在词典中找到 Term “Solr”,得到 “Solr” 对应的文档链表。

合并链表,对两个文档链表做交集运算,合并后的结果既包含 “Lucene” 也包含 “Solr”。

③OR
指多个集合求并集。比如,若要查找包含字符串 “Luence” 或者包含字符串 “Solr” 的文档,则查找步骤如下:

在词典中找到 Term “Lucene”,得到 “Lucene” 对应的文档链表。

在词典中找到 Term “Solr”,得到 “Solr” 对应的文档链表。

合并链表,对两个文档链表做并集运算,合并后的结果包含 “Lucene” 或者包含 “Solr”。

④NOT
指对多个集合求差集。比如,若要查找包含字符串 “Solr” 但不包含字符串 “Lucene” 的文档,则查找步骤如下:

在词典中找到 Term “Lucene”,得到 “Lucene” 对应的文档链表。

在词典中找到 Term “Solr”,得到 “Solr” 对应的文档链表。

合并链表,对两个文档链表做差集运算,用包含 “Solr” 的文档集减去包含 “Lucene” 的文档集,运算后的结果就是包含 “Solr” 但不包含 “Lucene”。

通过上述四种查询方式,我们不难发现,由于 Lucene 是以倒排表的形式存储的。

所以在 Lucene 的查找过程中只需在词典中找到这些 Term,根据 Term 获得文档链表,然后根据具体的查询条件对链表进行交、并、差等操作,就可以准确地查到我们想要的结果。

相对于在关系型数据库中的 “Like” 查找要做全表扫描来说,这种思路是非常高效的。

虽然在索引创建时要做很多工作,但这种一次生成、多次使用的思路也是非常高明的。

————————————————
原文作者:CrazyZard
转自链接:https://learnku.com/articles/40398
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请保留以上作者信息和原文链接。


http://www.ppmy.cn/news/62753.html

相关文章

Python爬虫入门之爬虫解析提取数据的四种方法

本文主要介绍了Python爬虫入门之爬虫解析提取数据的四种方法,通过具体的内容向大家展现,希望对大家Python爬虫的学习有所帮助。 基础爬虫的固定模式 笔者这里所谈的基础爬虫,指的是不需要处理像异步加载、验证码、代理等高阶爬虫技术的爬虫…

怎么控制别人的电脑屏幕?

为什么需要控制别人的屏幕? 我们不可避免地会遇到一些情况,比如我们需要为我们的朋友、同事或家人提供有关 IT 相关问题的帮助,如果他们不知道它该怎么处理这些问题该怎么办呢? 这时,我们可能需要用我们的电脑…

js - typeof与instanceof类型判断的区别

1,typeof 描述:运算符返回一个字符串,表示操作数的类型。 常用的类型判断 console.log(typeof 42); // numberconsole.log(typeof "blubber"); // stringconsole.log(typeof true); // booleanconsole.log(…

为什么我们要使用向量化运算

问题背景 如果你是matlab用户,你一般都会使用向量化运算进行编程。原因也许很简单,因为matlab针对向量化运算在底层做了深度优化,尤其是针对矩阵乘法调用了MKL之类的高度优化的第三库来加速。所以我们在推演算法的阶段,尽量的以向…

蓝牙网状网络的基本原理及应用开发

借助蓝牙 5 的网状网络功能,开发人员可以增强无线连接系统(如物联网设备)的通信范围和网络可用性。但是,网状网络的低功耗无线硬件设计与网状网络软件开发之间存在着复杂的层次,这可能会使开发人员迅速陷入混乱并危及项…

npm的使用和命令

3.0 npm 什么是npm 是node管理包的工具 3.1 初始化包管理描述文件 package.json npm init // 会询问你每次的选项 或 npm init -y // 不询问你选项,默认就是确定 首先建立一个文件在路径里面全选写cmd 然后打开环境 在里面写npm init -y回车 就会在你原来空的文…

C++中向线程传递参数的几次方式

在C中&#xff0c;向线程中传递参数有几种方法。以下是其中的几种&#xff1a; 1.使用std::thread构造函数的可变参数模板。可以将要传递的参数作为构造函数的后续参数传递。例如&#xff1a; #include <iostream> #include <thread>void func(int a, const std:…

327页16万字市智慧人社项目建设方案(word可编辑)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除 第 1 章 项目建设总体框架设计 1.1 系统总体架构设计 市智慧人社项目从总体逻辑上可分为信息访问层、门户层、应用服务层、应用支撑层、数据资源层和基础设施层等六个层次&a…