暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

ElasticSearch的核心-Apache Lucene 是什么

笨鸟之路 2021-04-19
1132

首先了解四个基本概念:

文档document):索引与搜索的主要数据载体,它包含一个或多个字段,存放将要写入索引或将从索引搜索出来的数据。
字段field):文档的一个片段,它包括两个部分:字段的名称和内容。
词项term):搜索时的一个单位,代表文本中的某个词。
词条token):词项在字段中的一次出现,包括词项的文本、开始和结束的位移以及类型。


Apache Lucene 将写入索引的所有信息组织成一种名为倒排索引( inverted index)的结构。该结构是一种将词项映射到文档的数据结构,其工作方式与传统的关系数据库不同,你大可以认为倒排索引是面向词项而不是面向文档的。接下来我们看看简单的倒排索引是什么样的。例如,我们有一些只包含 title 字段的文档,如下所示:

  • ElasticSearch Server(文档 1)

  • EasteringElasticSearch(文档 2)

  • Apache solr 4 Cookbook(文档 3)

而索引后的结构示意图如下所示。

正如你所见,每个词项指向该词项所出现过的文档数。这种索引组织方式支持快速有效的搜索操作,例如基于词项的查询。除了词项本身以外,每个词项还有一个与之关联的计数(即文档频率),用来告诉 Lucene 这个词项在多少个文档中出现过。
实际中 Lucene 创建的索引更为复杂,也更先进,因为索引中还存储了很多其他信息,如词向量(为单个字段创建的小索引,存储该字段中所有的词条)、各字段的原始信息、文档删除标记等。然而,你只需知道 Lucene 索引中数据是如何组织的即可,而不用知道到底存储了哪些东西。
每个索引由多个( segment)组成,每个段只会被创建一次但会被查询多次。索引期间,段经创建就不会再被修改。例如,文档被删除以后,删除信息被单独保存在一个文件中,而段本身并没有修改。
多个段会在一个叫作段合并( segments merge) 的阶段被合并在一起,而且要么强制执行,要么由 Lucene 的内在机制决定在某个时刻执行,合并后段的数量更少,但是更大。段合并非常耗 I/O,且合并期间有些不再使用的信息也将被清理掉,如被删除的文档。对于容纳相同数据的索引,段的数量较少时,搜索速度更快。尽管如此,还是需要强调一下:因为段合并非常耗 I/O,请不要强制进行段合并,你只需要仔细配置段合并策略,剩余的事情 Lucene 会自行搞定。
那么,文档中的数据是如何转化为倒排索引的,而查询串又是如何转换为
可用于搜索的词项的?这个转换过程称为分析(analysis)。 
文本分析由分析器来执行,而分析器由分词器(tokenizer)、过滤器(filter)和字符映射器组成(character mapper)。
Lucene的分词器用来将文本切割成词条。其中携带各种额外信息的词项,包括:词项在原始文本中的位置、词项的长度。分词器的工作成果称为词条流,因为这些词条被一个接一个地推送给过滤器处理。
除了分词器,过滤器也是Lucene分析器的组成部分,过滤器数量可选,可为0个或者多个,用于处理词条流中的词条。如,可以移除、修改词条流中的词条,甚至可以创造出新的词条。Lucene提供了很多现成的过滤器,也可根据需要自定义实现新的过滤器。如:
  • 小写过滤器

    将所有词条转化成小写。


  • ASCII过滤器

    移除词条中所有非ASCII字符。


  • 同义词过滤器:根据同义词规则,将一个词条转化为另一个词条。 

  • 多语言词干还原过滤器:将词条的文本部分归约到它们的词根形式,即词干还原。

当分析器中有多个过滤器时,会逐个处理,理论上可以有无限多个过滤器。
最后我们介绍字符映射器,它用于调用分词器之前的文本预处理操作,如 HTML 文本的去标签处理。 

索引与查询
Lucene 以及所有基于 Lucene 的软件,是如何控制索引和查询操作的。
在索引期, Lucene 会使用你选择的分析器来处理文档中的内容,并可以对不同的字段使用不同的分析器,例如,
文档的 title 字段与 description 字段就可以使用不同的分析器
在检索时,如果使用了某个查询分析器(query parser),那么查询串就会被分析。当然,你也可以选择不进行查询分析。
有一点需要牢记, ElasticSearch 中有些查询会被分析,而有些则不会。例如,前缀查询( prefix query)不会被分析,而匹配查询( match query)会被分析。
你还应该记住,索引期与检索期的文本分析要采用同样的分析器,只有查询分析出来的词项与索引中词项能匹配上,才会返回预期的文档集。例如,如果在索引期使用了词干还原与小写转换,那么在查询期也应该对查询串做相同的处理,否则查询可能不会返回任何结果。 

Lucene 查询语言

ElasticSearch 提供的一些查询类型( query type)支持 Apache Lucene 的查询解析语法,因此,我们应该深入了解 Lucene 的查询语言并加以描述。

Lucene 中,一个查询通常被分割为词项与操作符Lucene 中的词项可以是单个词,也可以是一个短语(用双引号括起来的一组词)。如果设置了查询分析过程,那么预先选定的分析器将会对查询中的所有词项进行处理。

查询中也可以包含布尔操作符,用于连接多个词项,使之构成从句( clause)。有以下这些布尔操作符:

  • AND :它的含义是,文档匹配当前从句当且仅当 AND 操作符左右两边的词项都在文档中出现。例如,执行 apache AND lucene 这样的查询,只有同时包含 apache 和Lucene 这两个词项的文档才会返回给用户。 
  • OR :它的含义是,包含当前从句中任意词项的文档都会被视为与该从句匹配。例如,执行 apache OR lucene 这样的查询,任意包含词项 apache 或词项 lucene 的文档都会返回给用户。 
  • NOT :它的含义是,与当前从句匹配的文档必须不包含 NOT 操作符后面的词项。例如,执行 lucene NOT elasticsearch 这样的查询,只有包含词项 lucene 且不包含词项 elasticsearch 的文档才会返回给用户。


此外,我们还可以使用以下操作符:
  • + :它的含义是,只有包含 + 操作符后面词项的文档才会被认为是与从句匹配。例如,查找那些必须包含 lucene,但是 apache 可出现可不出现的文档,可执行查询:
    +lucene apache。

  • - :它的含义是,与从句匹配的文档不能出现 - 操作符后的词项。例如,查找那些包含 lucene 但不包含 elasticsearch 的文档,可以执行查询:+lucene-elasticsearch。如果查询中没有出现前面提到过的任意操作符,那么默认使用 OR 操作符。

另外,你还可以使用圆括号对从句进行分组,以构造更复杂的从句,例如:
elasticsearch AND (mastering OR book) 。

本章小结:

  1. Apache Lucene 是什么。

  2. Lucene 的整体架构。

  3. 文本分析过程是如何实现的。

  4. Apache Lucene 的查询语言。

文章转载自笨鸟之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论