Elasticsearch实战(五)-倒排索引与分词
1 倒排索引
1.1 书的目录和索引
- 正排索引即目录页,根据页码去找内容
- 倒排索引即索引页,根据关键词去找对应页码
1.2 搜索引擎
正排索引
文档Id =》文档内容、单词的关联关系倒排索引
单词 =》 文档Id的关联关系左:正排索引 =》 右:倒排索引
倒排索引查询流程
查询包含"搜索引擎”的文档
- 通过倒排索引获得"搜索引擎”对应的文档Id有1和3
- 通过正排索引查询1和3的完整内容
- 返回最终结果
1.3 倒排索引的组成
1.3.1 单词词典( Term Dictionary )
倒排索引的重要组成
- 记录所有文档的单词 ,一般都比较大
- 记录单词到倒排列表的关联信息
单词字典的实现一般是用B+ Tree ,示例如下
1.3.2 倒排列表( Posting List )
记录了单词对应的文档集合,由倒排索引项( Posting )组成。
倒排索引项( Posting )主要包含如下信息:
- 文档Id ,用于获取原始信息
- 单词频率( TF, Term Frequency ),记录该单词在该文档中的出现次数,用于后续相关性算分
- 位置( Position)
记录单词在文档中的分词位置(多个) , 用于做词语搜索( Phrase Query ) - 偏移( Offset )
记录单词在文档的开始和结束位置,用于做高亮显示
案例
以搜索引擎为例
- 单词字典与倒排列表整合在一起的结构
ES存储的是JSON格式文档,其中包含多个字段,每个字段都有自己的倒排索引。
2 分词
将文本转换成一系列单词的过程,也称文本分析,在 ES 里称为 Analysis。
比如文本【JavaEdge 是最硬核的公众号】,分词结果是【JavaEdge、硬核、公众号】
2.1 Analyzer-分词器
分词器是 ES 专门处理分词的组件,组成如下:
2.1.1 Character Filters
在Tokenizer之前对原始文本进行处理,比如增加、删除或替换字符等。
针对原始文本进行处理,比如去除 html 特殊标记符,自带的如下:
- HTML Strip 去除 html 标签和转换 html 实体
- Mapping 进行字符替换操作
- Pattern Replace 进行正则匹配替换
会影响后续tokenizer解析的postion和offset信息
2.1.2 Tokenizer
将原始文本按照一定规则切分为单词,内置:
- standard 按单词进行分割
- letter 按非字符类进行分割
- whitespace 按空格进行分割
- UAX URL Email 按 standard 分割,但不会分割邮箱和 url
- NGram 和 Edge NGram 连词分割
- Path Hierachy 按文件路径进行分割
示例:
POST _analyze
{"tokenizer":"path_hierarchy","text":"/one/two/three"
}
2.1.3 Token Filters
针对 tokenizer 处理的单词进行再加工,比如转小写、删除或新增等处理,内置:
- lowercase 将所有 term 转换为小写
- stop 删除 stop words
- NGram 和 Edge NGram 连词分割
- Synonym 添加近义词的 term
示例
// filter 可以有多个
POST _analyze
{"text":"a Hello world!","tokenizer":"standard","filter":["stop", // 把 a 去掉了"lowercase",// 小写{"type":"ngram","min_gram":"4","max_gram":"4"}]
}
// 得到 hell、ello、worl、orld
分词器的调用顺序
3 Analyze API
ES 提供了一个测试分词的 API 接口,方便验证分词效果,endpoint 是 _analyze:
3.1 指定 analyzer
request
POST _analyze
{"analyzer":"standard", # 分词器"text":" JavaEdge 公众号" # 测试文本
}
response
{"tokens" : [{"token" : "java", # 分词结果"start_offset" : 1, # 起始偏移"end_offset" : 5, # 结束偏移"type" : "<ALPHANUM>","position" : 0 # 分词位置},{"token" : "edge","start_offset" : 6,"end_offset" : 10,"type" : "<ALPHANUM>","position" : 1}]
}
3.2 指定索引中的字段
POST 测试的索引/_analyze
{"field":"username", # 测试字段"text":"hello world" # 测试文本
}
3.3 自定义分词器
POST _analyze
{"tokenizer":"standard","filter":["lowercase"], # 自定义"text":"hello world"
}
- 之前的默认分词器大写
- 自定义小写分词器
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
- THU Lexical Analyzer for Chinese ,由清华大学自然语言处理与社会人文计算
实验室研制推出的一套中文词法分析工具包,具有中文分词和词性标注功能
https://github.com/microbun/elasticsearch-thulac-plugin
6 自定义分词器
当自带的分词无法满足需求时,可以自定义分词器,通过定义 Character Filters、Tokenizer、Token Filter 实现。自定义的分词需要在索引的配置中设定,示例如下所示:
- 自定义如下分词器
// 自定义分词器
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
7 分词使用说明
分词会在如下两个时机使用:
创建或者更新文档时(Index Time)
会对相应的文档进行分词处理
索引时分词是通过配置Index Mapping中每个字段的analyzer属性实现的。不指定分词时,使用默认standard。
查询时(Search Time)
会对查询语句进行分词。查询时分词的指定方式:
- 查询的时候通过analyzer指定分词器
- 通过index mapping设置
search_analyzer
实现
分词的最佳实践
- 明确字段是否需要分词,不需要分词的字段就将 type 设置为 keyword,可以节省空间和提高写性能。
- 善用 _analyze API,查看文档的具体分词结果
- 多动手测试
参考
- https://blog.csdn.net/weixin_38118016/article/details/90416391
- https://mp.weixin.qq.com/s?__biz=MzU1NDA4NjU2MA==&mid=2247486148&idx=1&sn=817027a204650763c1bea3e837d695ea&source=41#wechat_redirect
Elasticsearch实战(五)-倒排索引与分词相关推荐
- ElasticSearch(五) 倒排索引与分词
title: ElasticSearch(五) 倒排索引与分词 tags: ElasticSearch author: Clown95 倒排索引与分词 倒排索引 Elasticsearch 使用一种称 ...
- Elasticsearch实战(五)---高级搜索 Match/Match_phrase/Term/Must/should 组合使用
Elasticsearch实战-Match/Match_phrase/term/filter 及Must should 组合并列使用 文章目录 Elasticsearch实战-Match/Match_ ...
- Elasticsearch实战(四)---中英文分词及拼音搜索
Elasticsearch实战-中英文分词及拼音搜素 文章目录 Elasticsearch实战-中英文分词及拼音搜素 1.ElasticSearch 中英文分词插件 1.1 分词插件 1.2 默认分词 ...
- Elasticsearch实战(十五)---查询query,filter过滤,结合aggs 进行局部/全局聚合统计
Elasticsearch实战-查询query,filter过滤,结合aggs 进行局部/全局聚合统计 文章目录 Elasticsearch实战-查询query,filter过滤,结合aggs 进行局 ...
- ElasticSearch实战系列五: ElasticSearch的聚合查询基础使用教程之度量(Metric)聚合
Title:ElasticSearch实战系列四: ElasticSearch的聚合查询基础使用教程之度量(Metric)聚合 前言 在上上一篇中介绍了ElasticSearch实战系列三: Elas ...
- elasticsearch实战三部曲之三:搜索操作
elasticsearch实战三部曲之三:搜索操作 2019年01月13日 21:35:18 博陵精骑 阅读数:1367 标签: elasticsearch 更多 个人分类: elasticsearc ...
- Elasticsearch 中为什么选择倒排索引而不选择 B 树索引
那么到这里我们就可以思考这个问题了,假如索引值本身就很大,那么 B+ 树是不是性能会急剧下降呢?答案是肯定的,因为当索引值很大的话,一个节点能存储的数据会大大减少(一个节点默认是 16kb 大小),B ...
- Elasticsearch 实战 - 第四讲:ES 高级查询
Elasticsearch 实战 - 第四讲:ES 高级查询 Elasticsearch 实战系列文章: 一.高级查询 1.简介 2.结果排序 3.分页查询 4.检索查询 5.关键字查询 6.高亮显示 ...
- Elasticsearch 多语言及中文分词与检索详解
文章目录 1. 自然语言与查询 Recall 2. 混合多语言的挑战 3. 分词的挑战 4. 中文分词方法的演变 - 字典法 5. 中文分词方法的演变 - 基于统计法的机器学习算法 6. 中文分词器现 ...
最新文章
- arial字体可以商用吗_每次做PPT都不知该怎么选字体?6种万能字体搭配组合送你...
- List,Set,Collection,Collections比较
- 【错误记录】Windows 系统 bat 脚本报错 ( Java 生成 bat 脚本乱码处理 | 输出 GB2312 字符串 | Windows 中的换行时 \r\n )
- QML编程之旅 -- 事件处理
- 微服务【1.1】Swagger的使用
- 侏罗纪世界手游显示无法登陆到服务器,《侏罗纪世界手游》不能玩 解决攻略...
- Android 8.0 EditText 焦点无法移动到其他控件
- 【毕业设计】jsp+sql毕业生招聘系统毕业设计(系统+论文+英文文献+综合材料)
- 安装过mysql和p_MAC下安装与配置MySQL
- SHA1算法 c语言(参考其他修改)
- Java实现:学生管理系统
- 算术平均、几何平均、调和平均、平方平均和移动平均
- matlab 齐次线性方程组,Matlab中利用null函数解齐次线性方程组
- 数据统计分析——常用统计检验方法
- poj 1840(数的hah)
- 设置图片的透明度从左到右渐变
- mac虚拟摄像头开发
- Matlab 向量的处理
- 用例图包含关系、扩展关系、泛化关系解析
- 域名转换为IP地址示例