ElasticSearch映射和分析

ElasticSearch一切为了搜索,那么它是如何实现搜索功能的呢?从3个方面了解搜索功能的实现,分别是倒排索引(inverted index),分析器和映射

倒排索引(inverted index)

  1. 什么是映射:
    映射(mapping)将每个字段匹配为一种确定的类型(string,number,booleans,date等),类似于MySql数据库中的schema。
  2. 什么是分析:
    分析(analysis)对文本进行分词建立起供索引用的反向索引。

在传统的数据库中通过创建索引结构(例如B+树)快速索引信息,而ES和Lucene使用一种叫做倒排索引的结构实现检索目的。

所谓倒排索引,就是对文本进行切分出不同的词组短语,将每个词组短语出现在的文档中进行标记,在检索中通过检查标记的词组短语信息定位原始文本。这种方法相对一般通过原始文本进行正向检索而言属于反向进行,所以称为倒排

举个例子:
假设原始文本有两个,分别为“我爱北京天安门”和“我爱上海南京路”
原始文本“我爱北京天安门”,首先切分词组为“我”,“爱”,“北京”,“天安门”,同样的其他文档也会被切分。然后生成一个词组排序列表,如下表所示

词组 “我爱北京天安门” “我爱上海南京路”
✔️ ✔️
✔️ ✔️
北京 ✔️ X
天安门 ✔️ X
上海 X ✔️
南京路 X ✔️

之后当用户输入“我爱北京天安门”进行检索的时候,同样的输入文本先按照相同的切分方式切分,到排序列表中匹配,找到满足的文档。输入拆分成“我”,“爱”,“北京”,“天安门”,在表中刚好存在四个词组全部匹配的文档,返回最终查询结果。

分析器

显然上面的例子中最难的部分就是对文本的切分,英文单词与单词之间有空格,句子间还有标点符号,相对中文而言切分更为容易。而中文除了标点符号以外没有明显的分隔,切分涉及到词义的理解,所以在切分的算法实现上更加困难。

在ES中切分是由分析器完成的,一个分析器包括三个步骤:

  • 字符过滤器(character filter):去除多余的无用字符。
  • 分词器(tokenizer):将文本按照词进行切分,ES提供多种分词器,默认使用的标准分词器、语言分词器、空格分词器、简单分词器等。
  • 标记过滤器(token filters):对已经进行拆分的词进行修改、增加、去掉等操作。

经过三步骤的操作后创建倒排索引。

在搜索文档时,查询的字符需要经过同样的分析器处理,确保产生与倒排索引一致的单词列表。

一个自定义分词器的例子

依据业务需求主要是分词器和标记过滤器配合使用,还是文本“我爱北京天安门”,希望根据输入的词联想出可能结果,即输入“我爱”,“我”或者“北京”等都可以提示”我爱北京天安门”。

那么tokenizer使用keyword即不分词,token filters使用Edge NGram从后往前一个字符一个字符的分词,在倒排索引中拆分的结果是,“门,安门,天安门,京天安门,北京天安门,爱北京天安门,我爱北京天安门”,这样每次输入任意一个关键字向后进行通配符匹配时,都会命中相应的结果,完成模糊查询。

ES有很多现成的字符过滤器、分词器和标记过滤器提供给我们使用,具体每个分析器的功能需要查询ES的官方文档,根据业务需求做出合适的选择。

映射

前面提到了映射的概念,这里具体说明以下几点,需要在开发时加以特别注意:

  1. 在添加包含新字段的文档时,如果没有指定字段类型,ES会使用动态映射猜测字段类型。类型包括json的基本类型,如布尔型、字符串、整型、浮点型等。

  2. 在创建索引时指定映射类型,新增字段时也可以指定类型,建议对字段进行类型映射,以免由于ES猜测字段类型加之分析器分词导致搜索时产生与设计不一致的结果。

  3. 已经被映射的字段不可以再修改映射,因为这个字段数据已经被索引,如果修改映射,被索引的数据不能正确地搜索到。

你可能感兴趣的:(ElasticSearch映射和分析)