倒排索引
倒排索引以字或词为关键字进行索引,表中关键字所对应的记录表项记录了出现这个字或词的所有文档,一个表项就是一个字表段。它记录该文档的ID和字符在该文档中出现的位置情况。
以下三个文档去除停用词后构造倒排索引
- Term(单词): 一段文本经过分析器以后就会输出一串单词,这一个个的就叫做Term
- Term Dictionary(单词字典) 顾名思义,它里面维护的是Term,可以理解为Term的集合
- Term Index(单词索引): 为了更快的找到某个单词,我们为单词建立索引
- Posting List(倒排列表): 倒排列表记录了出现过的某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项。
根据倒排列表,即可知哪些文档包含某个单词。
(PS: 如果类比现代汉语词典的话,那么Term就相当于词语,Term Dictionary相当于汉语词典本身,Term Index相当于词典的目录索引)
上面的例子,Elasticsearch建立的索引大致如下:
name字段
age字段
gender字段
address字段
Elasticsearch分别为每个字段都建立一个倒排索引。比如,在上面”张三“,”北京市“,22 这些都是Term,而[1,3]就是Posting List。Posting list就是一个数组,存储了所有符合某个Term的文档ID。
倒排索引的组成
-
单词列表:实现一般用B+树,
-
倒排列表
- 文档id用于获取原始信息
- 单词频率(TF,Term Frequency),记录该单词在该文档中出现的次数。
- 位置(Posting),记录单词在文档中的分词位置,用于做词语搜索
- 偏移(Offset),记录单词在文档的开始和结束位置,用于高亮显示
建立了B-Tree来快速找到Terms索引
MyISAM中,索引和数据是分开,通过索引可以找到记录的地址,进而可以找到这条记录
前面分成了三步,其实可以把Term Index和Term Dictionary看成一步,就是找Term。因此可以这样理解倒排索引:通过单词找到对应的倒排列表,根据倒排列表中的倒排进而可以找到文档记录
倒排索引不可变的好处
- 不需要锁,提升并发能力,避免锁问题
- 数据不变,一直保存在os cache中,只要cache内存足够
- filter cache一直驻留在内存,因为数据不变
- 可以压缩,节省cpu和io开销
分词
分词是将文本转换为一系列单词的过程,也可以叫文本分析,在ES里面称为Analysis
比如下面这一句
- Elasticsearch是最流行的搜索引擎
- Elasticsearch / 流行 / 搜索引擎
分词器有以下组成:
- Character Filter: 针对原始文本进行处理,比如去除html标签
- Tokenizer: 将原始文本按照一定规则切分为单词
- Token Filter: 针对Tokenizer处理的单词进行再加工,比如转小写,删除或增新等处理
Analyzer分词器的调用顺序
- Character Filter
- Tokenizer
- Token Filter
预定义的分词器
- Standard Analyzer
默认分词器
按词切分,支持多语言
小写处理 - Simple Analyzer
按照非字母切分
小写处理 - Whitespace Analyzer
空白字符作为分隔符 - Stop Analyzer
相比Simple Analyzer多了去除请用词处理
停用词指语气助词等修饰性词语,如the an,的,这等 - keyword Analyzer
不分词,直接将输入作为一个单词输出 - pattern Analyzer
通过正则表达式自定义分词符
默认是\W+ ,即非字词的符号作为分隔符 - Language Analyzer
提供了30+种常见的语言的分词器
自定义分词器
Character Filters
- 在Tokenizer之前对原始文本进行处理,比如增加,删除或替换字符等。
- 自带的如下:
- HTML Strip Character Filter:去除HTML标签和转换HTML实体
- Mapping Character Filter:进行字符串替换操作
- Pattern Replace Character Filter:进行正则匹配替换
- 会影响后续tokenizer 解析的position和offset信息
Tokenizers
- 将原始文本按照一定规则切分为单词(term or token)
- 自带如下:
- standard按照单词进行分割
- letter按照非字符进行分割
- whitespace按照空格进行分割
- UXA URL Email按照standard进行分割,但不会分割邮箱和URL
- Ngram 和Edge NGram连词分割
- Path Hierarchy 按照文件路径进行分割
Token Filters
- 对于tokenizer输出的单词(term) 进行增加,删除,修改等操作
- 自带的如下:
- lowercase 将所有的term转为小写
- stop删除停用词
- Ngram和Edge NGram连词分割
- Synonym添加近义词的term
自定义分词。。。。
分词使用说明
分词会在如下两个时机使用:
- 创建或更新文档时,会对响应的文档进行分词处理
- 查询(Search Time),会对查询语句进行分词
- 查询时通过analyzer指定分词器
- 通过index mapping设置search_analyzer实现
- 一般不需要特别指定查询时分词器,直接使用索引分词器即可,否则会出现无法匹配的情况
分词使用建议
- 明确字段是否需要分词,不需要分词的字段就将type设置为keyword,可以节省空间提高性能
- 善用_analyze API ,查看文档的分词结果