正排索引与倒排索引
讲述倒排索引之前我们先搞清楚什么是正排索引,平时我们看书的目录就是典型的正排索引,通过目录去寻找我们需要的内容。
倒排索引则是正好与之相反通过内容中的关键字去查找对应的文章。本质上就是通过输入某一些关键字来获取到所需要的文章,平时用的百度和谷歌就是如此。道理简单实现上会有很多细节处理,在茫茫没多的文章中找到你符合你需要的文章,这个过程非常复杂。
倒排索引详解
倒排索引的组成
倒排索引是搜索引擎的核心,主要包括两个部分:
单词词典(Term Dictionary)
记录所有文档的单词,一般都占用空间都比较大。
记录单词与倒排列表的关联关系(也就是记录了这个单词在哪写文档中出现了)。
倒排列表(Posting List)
倒排列表(Posting List)记录了单词对应的文档集合,由倒排索引项(Posting)组成。
倒排索引项(Posting)主要包含如下信息:
文档id,用于获取原始信息。
单词词频(TF,Term Frequency),记录单词在文档中的出现次数,用于后续相关性算分。
位置(Position),记录该单词在文档中的分词位置(可能会有多个),用于做词语搜索(Phrase Query)。例如:搜索“苹果手机”,会被拆分成“苹果”和“手机”进行搜索,此时Position就会用做对手机这两个词的前后位置进行判断时使用。
偏移(Offset),记录单词在文档中的开始和结束位置,用于做高亮显示。
单词词典(Term Dictionary)与倒排列表(Posting List)结合起来的示例图
es中的倒排索引
es存储的是一个json格式的文档,其中包含多个字段,每个字段都会有自己的倒排索引。类似如下图:
分词介绍
分词是指将文本转换成一系列单词(term or token)的过程,也可以叫做文本分析,在es里称为Analysis,如下图所示:
分词器
分词起是es中专门处理分词的组件,英文为Analyzer,它的组成如下:
Character Filters(可以有多个)
针对原始文本进行处理,不如去除html特殊标记符。
Tokenizer(只允许有一个)
将经过Character Filters处理过的文本按照一定的规则进行拆分。
Token Filter(可以有多个)
针对Tokenizer切分过的单词进行在加工,英文比如转小写,以中文为例,还可以去掉“的”、“这”等字(Stop Words)。
调用顺序
Analyze API
es提供了一个测试分词的api接口,方便验证分词结果,endpoint时_analyze。
可以直接指定analyzer进行测试。standard是es默认的分词器。
可以直接指定索引中的字段进行测试。使用场景,已经创建好的Index,针对这个Index的一个Field进行查询时,与预期不相符时。
可以自定义分词起进行测试。
不加"filter":["lowercase"]的返回:
加上"filter":["lowercase"]的返回:
es自带的分词器
Standard Analyzer
默认分词器。
其组成如图,特性:
按词切分,支持多语言。
小写处理。
Simple Analyzer
其组成如图,特性:
按照非字母进行切分。
小写处理
WhiteSpace Analyzer
其组成如图,特性:
按照空格进行切分。
Stop Analyzer
Stop Words指语气助词等修饰性的词语,比如the、an、的、这等。
其组成如图,特性:
相比Simple Analyzer多了Stop words处理。
Keyword Analyzer
其组成如图,特性:
不分词,直接将输入作为一个单词进行输出。
Pattern Analyzer
其组成如图,特性:
通过正则表达式自定义分隔符。
默认是\W+,即非字词的符号作为分隔符。
Language Analyzer
提供30+种常见语言的分词器。
中文分词
难点
在英文中单词与单词之间是以空格作为自然分解符,汉语中没有形式上的分界符。
上下文不同分词的结果迥异,比如交叉歧义问题,比如下面两种分词都合理。
乒乓球拍/卖/完了。
乒乓球/拍卖/完了。
常用的见中文分词器材。
ik
jieba
HanLP
THULAC
自定义分词器
当自带分词器无法满足需求时,可以自定义分词器。
通过自定义Character Filters、Tokenizer、Token Filters实现。
Character Filters
在Tokenizer之前对原始文本进行处理,比如增加、删除、替换字符等。
es自带的Character Filters
HTML strip去除html标签和转换html实体。
Mapping进行字符串替换操作。
Pattern replace进行正则匹配替换。
会影响后续Tokenizer解析的position和offset信息。
Tokenizer
将Character Filters处理过的文本切分成单词。
自带的如下。
standard按照单词进行分割。
letter按照非字符类型进行分割。
whitespace按照空格进行分割。
UAX URL Email按照standard进行分割,但是不会分割URL和邮箱地址。
NGgram 和Edge NGgram连词分割。
Path hierarchy按照文件路径进行分割。
Token Filters
对于Tokenizer输出的单词进行处理,增加、删除、修改等操作。
es自带如下:
lowercase将所有单词转换为小写。
stop删除stop words。
NGgram 和Edge NGgram连词分割。
自定义分词器设置API
自定义分词器需要在索引配置中设定,如下所示:
自定义分词器验证
分词器的使用时机
创建或者更新文档时(Index Time),会对相应的文档进行分词处理。
查询时(Search Time),会对查询语句进行分词。