倒排索引、分析和映射

date
Jul 29, 2021
slug
elasticsearch-guide-invert-index-and-analyse
status
Published
tags
Elasticsearch
读书
summary
type
Page

倒排索引 Inverted Index

一般使用倒排索引(inverted index)结构实现快速的全文检索。首先对下面两个句子拆成单词,生成不重复词条的排序列表
  1. The quick brown fox jumped over the lazy dog
  1. Quick brown foxes leap over lazy dogs in summer
此时如果搜索 quick brown ,我们只需要查找包含每个词条的文档:
而且 Doc_1 能够匹配到两个词,所以相关度更好。
 

分词和标准化(tokenization and normalization)

上面的倒排索引还不够完美,比如:
  • Quick 和 quick 以独立的词条出现,然而用户可能认为它们是相同的词。
  • fox 和 foxes 非常相似, 就像 dog 和 dogs ;他们有相同的词根。
  • jumped 和 leap, 尽管没有相同的词根,但他们的意思很相近。他们是同义词。
可以对单词做一些标准化处理:
  • Quick 可以小写化为 quick 。
  • foxes 可以词干提取变为词根的格式为 fox 。类似的, dogs 可以为提取为 dog 。
  • jumped 和 leap 是同义词,可以索引为相同的单词 jump 。
这样得到的倒排索引像这样:
之后对搜索的关键词做同样的标准化,如将搜索词 Quick 转换成 quick 的过程。
 

分析和分析器 (Analysis and Analyzer)

分析 analysis 的过程主要做两件事情:
  • 将文本分词成独立的单词,这样适用于建立倒排索引
  • 将单独标准化提高单词的可搜索性,方便召回
分析器 analyzer 就是做这件事的,分析器 analyzer 内部有三种功能组成
  • 字符过滤器 character filters:字符串按顺序通过每个字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉 HTML,或者将 & 转化成 and。
  • 分词器 tokenizer:字符串被分词器分成独立的词条 term,一般的分词器遇到空格或标点符号就算一个词条。
  • Token 过滤器 token filters:这一步是将每个词条单独做处理,如小写化、移除停用词、添加同义词等。
当添加一个文档时,Elasticsearch 会对文档中全文字段做分析,从而建立倒排索引。
当搜索一个关键词时,Elasticsearch 会对关键词做分析,便于检索文档。
 

映射 Mapping

映射 Mapping 中可指定 field 的类型,如果类型是 text,还可以指定使用什么分析器:
 
保存数组类型
可以保存形如 { "tag": [ "search", "nosql" ]} 的 field 类型,任何 field 都可以保存多个值无需特殊指定,也就是说此时的 tag 字段,其类型依旧是 text 类型,查看此时 blogs 的 mapping 可以看到:
同样的,数组中每个元素的类型都必须满足 field 的定义,即 tag 中必须都是 text 类型,Elasticsearch 会使用第一个元素的类型作为整个 feild 的类型。
 
保存空类型
Lucene 中不能存储 null 值,下面三种 feild 会被认为是空的,不会被索引:
 
保存对象类型
形如在文档中加入 user 信息的形式:
查看其 mapping 结构:
由于 Lucene 不支持对象,所以 Elasticsearch 会把对象打平(flat),类似这样:
 
在数组中保存对象
处理形如下面这种文档:
也会被打平,不过不太一样的是会将每个属性放在一起打平:
这样的索引有个问题是,age 和 name 之间的联系丢失了。只能回答 ”Is there a follower who is 26 years old?“,但无法回答 ”Is there a follower who is 26 years old and who is called Alex Jones?“。要支持第二种查询,需要用到嵌套对象 nested object。
 

查询和过滤的区别 Query and Filter

查询问的问题是某文档对于搜索词的相关度怎么样,结果是相关度得分的高低。
过滤问的问题是某文档的字段是否满足某条件,结果是满足和不满足。
性能上来说,过滤性能会稍微好一些,除了全文搜索的字段,其他字段上的查询都应该使用过滤。
 

使用 explain 参数分析查询

 

相似度分数的计算

相似度分数有如下几个点影响:
  • 搜索词在该字段出现的频率:出现频率越高,相关性也越高。 字段中出现过 5 次要比只出现过 1 次的相关性高。
  • 搜索词在反向索引中出现的频率:频率越高,相关性越低。搜索词出现在多数文档中会比出现在少数文档中的权重更低。
  • 字段的长度:长度越长,相关性越低。 搜索词出现在一个短的 title 要比出现在一个长的 content 字段权重更大。
同样可以通过 explain 参数查看评分的细节,甚至可以指定一个不 match 的文档 id,查看为什么不匹配。
 

© 菜皮 2020 - 2023