ElasticSearch - 原理入门

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎:

  • 一个分布式的实时文档存储,每个字段可以被索引与搜索。
  • 一个分布式实时分析搜索引擎。
  • 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据。

映射关系如下图:

  • 什么是 index (索引) 

一个 索引 就是一个拥有几分相似特征的文档的集合。ES 将数据存储于一个或多个索引中,索引 就相当于 SQL 中的一个数据库。

  • 什么是 Type(类型)

类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。类比传统的关系型数据库领域来说,类型 相当于 表,7.x 版本默认使用 _doc 作为 type 。

  • 什么是 Document(文档)

文档是 Lucene 索引和搜索的 原子单位,它是包含了一个或多个域的容器,基于 Json 格式进行表示。文档有一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常被称为 多值域,每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。相当于 mysql 表中的 row 。

  • 什么是 Field (字段)

Field 是相当于数据库中的 Column。

检索原理

  • 用户将数据提交到Elastic Search 数据库中
  • 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据
  • 用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户。

1)为什么快?

空间换时间。

  • 通过分布式部署,将数据存储在多个节点。
  • 索引分片,查询可并发操作。
  • 把每个索引划分成多个分片,可以让查询并行进行。
  • 倒排索引(核心):将文档中的每个词与该词出现在哪些文档中进行映射并储存。检索时通过倒排索引快速找到包含所有搜索次的文档,不需要重新计算。
  • 索引优化:支持索引覆盖、索引下推等优化技术。快速通过跳表、Bitmap索引等组织检索,通过联合索引定位范围。
  • 异步请求处理。请求到达时立刻返回部分结果。
  • 内存存储:读写数据时减少磁盘访问次数。
  • 压缩:通过压缩技术尽可能的在内存中多放数据。

2)正向索引(正排索引)

从文档中查找字符串。关系型数据库使用的是正向索引。

3)反向索引(倒排索引)

从字符串查找文档。搜索引擎lucene使用的是反向索引。

Lucene的倒排索引(Inverted Index)是先在内存里生成,然后定期以段文件(segment file)的形式刷到磁盘的。

思考:Elasticsearch使用的倒排索引比关系型数据库的B-Tree索引快,为什么?
二叉树查找效率是logN,同时插入新的节点不必移动全部节点,所以用树型结构存储索引,能同时兼顾插入和查询的性能。因此在这个基础上,再结合磁盘的读取特性(顺序读/随机读),传统关系型数据库采用了B-Tree/B+Tree这样的数据结构。为了提高查询的效率,减少磁盘寻道次数,将多个值作为一个数组通过连续区间存放,一次寻道读取多个数据,同时也降低树的高度。

检索方式

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

1)单个词查询

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

2)AND

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

 (1)在词典中找到Term “lucene”,得到“lucene”对应的文档链表。

 (2)在词典中找到Term “solr”,得到“solr”对应的文档链表。

 (3)合并链表,对两个文档链表做交集运算,合并后的结果既包含“lucene”也包含“solr”。

3)OR

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

 (1)在词典中找到Term “lucene”,得到“lucene”对应的文档链表。

 (2)在词典中找到Term “solr”,得到“solr”对应的文档链表。

 (3)合并链表,对两个文档链表做并集运算,合并后的结果包含“lucene”或者包含“solr”。

4)NOT

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

 (1)在词典中找到Term “lucene”,得到“lucene”对应的文档链表。

 (2)在词典中找到Term “solr”,得到“solr”对应的文档链表。

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

 通过上述四种查询方式,我们不难发现,由于Lucene是以倒排表的形式存储的,所以在Lucene的查找过程中只需在词典中找到这些Term,根据Term获得文档链表,然后根据具体的查询条件对链表进行交、并、差等操作,就可以准确地查到想要的结果,相对于在关系型数据库中的“like”查找要做全表扫描来说,这种思路是非常高效的。虽然在索引创建时要做很多工作,但这种一次生成、多次使用的思路也是非常高明的。

posted @ 2024-07-21 12:32  李若盛开  阅读(1)  评论(0编辑  收藏  举报