1 倒排索引 1.1 书的文讲目录和索引 正排索引即目录页,根据页码去找内容 倒排索引即索引页,倒排根据关键词去找对应页码 1.2 搜索引擎 文档Id =》文档内容、索引单词的分词关联关系 单词 =》 文档Id的关联关系 倒排索引查询流程 查询包含"搜索引擎”的文档 1.3 倒排索引的组成 1.3.1 单词词典( Term Dictionary ) 倒排索引的重要组成 单词字典的实现一般是用B+ Tree ,示例如下 1.3.2 倒排列表( Posting List ) 记录了单词对应的文档集合,由倒排索引项( Posting )组成。倒排 倒排索引项( Posting )主要包含如下信息: 记录单词在文档的开始和结束位置,用于做高亮显示 案例 以搜索引擎为例 单词字典与倒排列表整合在一起的结构 ES存储的是JSON格式文档,其中包含多个字段,倒排每个字段都有自己的索引倒排索引。 2 分词 将文本转换成一系列单词的分词过程,也称文本分析,服务器租用文讲在 ES 里称为 Analysis。倒排 比如文本【JavaEdge 是索引最硬核的公众号】,分词结果是【JavaEdge、硬核、公众号】 2.1 Analyzer-分词器 分词器是 ES 专门处理分词的组件,组成如下: 2.1.1 Character Filters 在Tokenizer之前对原始文本进行处理,比如增加、删除或替换字符等。 针对原始文本进行处理,比如去除 html 特殊标记符,自带的如下: 会影响后续tokenizer解析的postion和offset信息 2.1.2 Tokenizer 将原始文本按照一定规则切分为单词,内置: 示例: POST _analyze{ "tokenizer":"path_hierarchy", "text":"/one/two/three"} 2.1.3 Token Filters 针对 tokenizer 处理的单词进行再加工,比如转小写、删除或新增等处理,内置: 示例 分词器的调用顺序 3 Analyze API ES 提供了一个测试分词的 API 接口,方便验证分词效果,endpoint 是 _analyze: 3.1 指定 analyzer request response 3.2 指定索引中的字段 3.3 自定义分词器 之前的默认分词器大写 自定义小写分词器 4 内置分词器 Standard Analyzer 默认分词器,按词切分,支持多语言,小写处理 Simple Analyzer 按照非字母切分,小写处理 Whitespace Analyzer 按空格切分 Stop Analyzer Stop Word 指语气助词等修饰性词语,比如 the、an、的、这等等,特性是相比 Simple Analyzer 多 Stop Word 处理 keyword Analyzer 不分词,直接将输入作为一个单词输出 Pattern Analyzer 通过正则表达式自定义分隔符,默认 \W+,即非字词的符号为分隔符 Language Analyzer 提供了 30+ 常见语言的分词器 5 中文分词 将一个汉字序列切分成一个个单独的词。在英文中,单词之间是以空格作为自然分界符,汉语中词没有一个形式上的分界符。而且中文博大精深,上下文不同,分词结果也大不相同。 比如: 以下是 ES 中常见的分词系统: IK 实现中英文单词的切分,可自定义词库,支持热更新分词词典 jieba python 中最流行饿分词系统,站群服务器支持分词和词性标注,支持繁体分词,自定义词典,并行分词 以下是基于自然语言处理的分词系统: Hanlp 由一系列模型与算法组成的 java 工具包,支持索引分词、繁体分词、简单匹配分词(极速模式)、基于 CRF 模型的分词、N- 最短路径分词等,实现了不少经典分词方法。目标是普及自然语言处理在生产环境中的应用。 https://github.com/hankcs/HanLP THULAC 实验室研制推出的一套中文词法分析工具包,具有中文分词和词性标注功能 https://github.com/microbun/elasticsearch-thulac-plugin 6 自定义分词器 当自带的分词无法满足需求时,可以自定义分词器,通过定义 Character Filters、Tokenizer、Token Filter 实现。自定义的分词需要在索引的配置中设定,示例如下所示: 自定义如下分词器 7 分词使用说明 分词会在如下两个时机使用: 创建或者更新文档时(Index Time) 会对相应的文档进行分词处理 索引时分词是通过配置Index Mapping中每个字段的analyzer属性实现的。不指定分词时,使用默认standard。 查询时(Search Time) 会对查询语句进行分词。查询时分词的指定方式: 分词的最佳实践 参考 【编辑推荐】// 自定义分词器 PUT test_index_name { "settings":{ "analysis":{ "analyzer":{ "my_customer_analyzer":{ "type":"custome", "tokenizer":"standard", "char_filter":["html_strip"], "filter":["lowercase", "asciifolding"] } } } } } // 测试自定义分词器效果: POST test_index/_analyze { "tokenizer":"keyword", "char_filter":["html_strip"], "text":"Is this <b>a box</b>?" } // 得到 is、this、a、box