Elastic学习之旅 (5) 倒排索引和Analyzer分词
大家好,我是Edison。
上一篇:ES文档的CRUD操作
重要概念1:倒排索引
在学习ES时,倒排索引是一个非常重要的概念。要了解倒排索引,就得先知道什么是正排索引。举个简单的例子,书籍的目录页(从章节名称快速知道页码)其实就是一个典型的正排索引。

而一般书籍的末尾部分的索引页,则是一个典型的倒排索引,是从关键词 到 章节名称 / 页码。

由上可知,对于图书来讲:目录页就是正排索引,索引页就是倒排索引。
而对于搜索引擎来讲:文档ID到文档内容和单词的关联是正排索引,而单词到文档ID的关系则是倒排索引。
我们可以从下面的两个表格来感受下正排索引和倒排索引的区别:

倒排索引的核心内容
倒排索引包含两个部分:
单词词典(Term Dictionary):记录所有文档的单词,记录单词到倒排列表的关联关系。单词词典一般都很大,一般都通过B+树 或 哈希拉链法 实现,以满足高性能的插入和查询。
倒排列表(Posting List):记录了单词对应的文档结合,由倒排索引项组成。倒排索引项(Posting)包括 文档ID、词频(TF,该单词在文档中出现的次数,用于相关性评分)、位置(Postion,单词在文档中分词的位置,用于语句搜索) 以及 偏移(Offset,记录单词的开始结束为止,实现高亮显示)
下图展示了ES中的一个例子:

ES中的JSON文档中的每个字段,都有自己的倒排索引。当然,我们可以指定对某些字段不做索引,以节省存储空间,但是这些字段就无法被搜索。
重要概念2:Analyzer
在ES中文本分析是其最常见的功能之一,文本分析(Analysis)是把全文转换为一系列单词(term)的过程,也叫作分词。
文本分析是通过Analyzer来实现,我们可以使用ES内置的分析器,也可以按需定制分析器。
除了在数据写入时会进行全文转换词条,在匹配Query语句时也需要用相同的分析器对查询语句进行分析。
ES中的内置分词器
Standard Analyzer - 默认分词器,按词切分,小写处理
Simple Analyzer - 按照非字母切分(符号被过滤),小写处理
Stop Analyzer - 小写处理,停用词过滤(the, a, is)
Whitespace Analyzer - 按照空格切分,不转小写
Keyword Analyzer - 不分词,直接将输入当做输出
Patter Analyzer - 正则表达式,默认 \W+(非字符分隔)
Language - 提供了30多种常见语言的分词器
Custom Analyzer - 自定义分词器
通过Analyzer进行分词
这里,我们来用_analyzer API做一些demo:
(1)Standard Analyzer
GET /_analyze
{
"analyzer": "standard",
"text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
分词结果:按词切分,默认小写(Quick被转成了quick)
{
"tokens" : [
{
"token" : "2",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<NUM>",
"position" : 0
},
{
"token" : "running",
"start_offset" : 2,
"end_offset" : 9,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "quick",
"start_offset" : 10,
"end_offset" : 15,
"type" : "<ALPHANUM>",
"position" : 2
},
{
"token" : "brown",
"start_offset" : 16,
"end_offset" : 21,
"type" : "<ALPHANUM>",
"position" : 3
},
{
"token" : "foxes",
"start_offset" : 22,
"end_offset" : 27,
"type" : "<ALPHANUM>",
"position" : 4
},
{
"token" : "leap",
"start_offset" : 28,
"end_offset" : 32,
"type" : "<ALPHANUM>",
"position" : 5
},
{
"token" : "over",
"start_offset" : 33,
"end_offset" : 37,
"type" : "<ALPHANUM>",
"position" : 6
},
{
"token" : "lazy",
"start_offset" : 38,
"end_offset" : 42,
"type" : "<ALPHANUM>",
"position" : 7
},
{
"token" : "dogs",
"start_offset" : 43,
"end_offset" : 47,
"type" : "<ALPHANUM>",
"position" : 8
},
{
"token" : "in",
"start_offset" : 48,
"end_offset" : 50,
"type" : "<ALPHANUM>",
"position" : 9
},
{
"token" : "the",
"start_offset" : 51,
"end_offset" : 54,
"type" : "<ALPHANUM>",
"position" : 10
},
{
"token" : "summer",
"start_offset" : 55,
"end_offset" : 61,
"type" : "<ALPHANUM>",
"position" : 11
},
{
"token" : "evening",
"start_offset" : 62,
"end_offset" : 69,
"type" : "<ALPHANUM>",
"position" : 12
}
]
}
(2)Simple Analyzer
GET /_analyze
{
"analyzer": "simple",
"text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
分词结果:非字母切分,忽略了数字2,小写处理
{
"tokens" : [
{
"token" : "running",
"start_offset" : 2,
"end_offset" : 9,
"type" : "word",
"position" : 0
},
......
]
}
(3)Whitespace Analyzer
GET /_analyze
{
"analyzer": "whitespace",
"text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
分词结果:按照空格切分,不转小写。可以看到,brown-foxes被看成是一个整体,并未像其他分词一样分为brown 和 foxes。此外,也不会强制换位小写,比如Quick就保留了大写。
{
"tokens" : [
......
{
"token" : "Quick",
"start_offset" : 10,
"end_offset" : 15,
"type" : "word",
"position" : 2
},
{
"token" : "brown-foxes",
"start_offset" : 16,
"end_offset" : 27,
"type" : "word",
"position" : 3
},
......
]
}
(4)Stop Analyzer
GET /_analyze
{
"analyzer": "stop",
"text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
分词结果:小写处理,停用词过滤(the, a, is),这里原文中的in, over, the都被过滤掉了。
(5)Keyword Analyzer
GET /_analyze
{
"analyzer": "keyword",
"text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
分词结果:不做任何分词处理,而是将输入整体作为一个term。通常用于不需要对输入做分词的场景。
{
"tokens" : [
{
"token" : "2 running Quick brown-foxes leap over lazy dogs in the summer evening.",
"start_offset" : 0,
"end_offset" : 70,
"type" : "word",
"position" : 0
}
]
}
(6)Pattern Analyzer
GET /_analyze
{
"analyzer": "pattern",
"text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
正则表达式,默认 \W+(非字符分隔)
新增一个表达式analyzer:
PUT my_index
{
"settings": {
"analysis": {
"analyzer": {
"my_email_analyzer": {
"type": "pattern",
"pattern": "\\W|_",
"lowercase": true
}
}
}
}
} POST my_index/_analyze
{
"analyzer": "my_email_analyzer",
"text": "John_Smith@foo-bar.com"
}
(7)Lanuage Analyzer
ES提供了多种语言的分词器:阿拉伯语、亚美尼亚语、巴斯克语、孟加拉语、巴西语、保加利亚语、加泰罗尼亚语、捷克语、丹麦语、荷兰语、英语、芬兰语、法语、加利西亚语、德语、希腊语、印地语、匈牙利语、印度尼西亚语、爱尔兰语、意大利语、拉脱维亚语、立陶宛语、挪威语、波斯语、葡萄牙语、罗马尼亚语、俄语、索拉尼语、西班牙语、瑞典语、土耳其语、泰国语。
这里我们看看English:
GET /_analyze
{
"analyzer": "english",
"text": "2 running Quick brown-foxes leap over lazy dogs in the summer evening."
}
分词结果:将running替换为了run,将foxes替换为fox,dogs替换为dog,evening替换为了even,in被忽略。
可以看到,ES支持的语言分词器中,没有支持中文,这是因为:中文分词存在较大的难点,不像英语那么简单。
不过,我们可以安装一些中文分词器的插件(plugin),比如ICU Analyzer, 它提供了unicode的支持,更好地支持亚洲语言。
elasticsearch-plugin install analysis-icu
ICU Analyzer的示例:
POST /_analyze
{
"analyzer": "icu_analyzer",
"text": "他说的确实在理"
}
分词结果:
[他,说的,确实,在,理]
小结
本篇,我们了解了ElasticSearch的另一个重要概念:倒排索引 和 一个重要工具:Analyzer,还通过一些demo了解了Analyzer的具体使用案例,它们帮助ElasticSearch实现了强大的搜索功能。
参考资料
极客时间,阮一鸣,《ElasticSearch核心技术与实战》

Elastic学习之旅 (5) 倒排索引和Analyzer分词的更多相关文章
- WCF学习之旅—第三个示例之四(三十)
上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) WCF学习之旅—第三个示例之三(二十九) ...
- Hadoop学习之旅二:HDFS
本文基于Hadoop1.X 概述 分布式文件系统主要用来解决如下几个问题: 读写大文件 加速运算 对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整 ...
- WCF学习之旅—第三个示例之二(二十八)
上接WCF学习之旅—第三个示例之一(二十七) 五.在项目BookMgr.Model创建实体类数据 第一步,安装Entity Framework 1) 使用NuGet下载最新版的Entity Fram ...
- WCF学习之旅—第三个示例之三(二十九)
上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) 在上一篇文章中我们创建了实体对象与接口协定,在这一篇文章中我们来学习如何创建WCF的服务端代码.具体步骤见下面. ...
- WCF学习之旅—WCF服务部署到IIS7.5(九)
上接 WCF学习之旅—WCF寄宿前的准备(八) 四.WCF服务部署到IIS7.5 我们把WCF寄宿在IIS之上,在IIS中宿主一个服务的主要优点是在发生客户端请求时宿主进程会被自动启动,并且你可以 ...
- WCF学习之旅—WCF服务部署到应用程序(十)
上接 WCF学习之旅—WCF寄宿前的准备(八) WCF学习之旅—WCF服务部署到IIS7.5(九) 五.控制台应用程序宿主 (1) 在解决方案下新建控制台输出项目 ConsoleHosting.如下 ...
- WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一)
上接 WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) 七 WCF服务的Windows 服务程序寄宿 这种方式的服务寄宿,和IIS一样有一个一样 ...
- WCF学习之旅—WCF服务的WAS寄宿(十二)
上接 WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) 八.WAS宿主 IIS ...
- WCF学习之旅—WCF服务的批量寄宿(十三)
上接 WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) WCF学习之旅—WCF ...
- WCF学习之旅—第三个示例之五(三十一)
上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) WCF学习之旅—第三个示例之三(二十九) WCF学习 ...
随机推荐
- 如何通过物理备份将线下SQL Server迁移到阿里云RDS for SQL Server
简介 物理备份迁移是将SQL Server数据库迁移至阿里云RDS的推荐方法.此方案能够确保数据完整性,同时显著降低迁移过程中的风险及停机时间.相较于逻辑导出导入或第三方工具等其他迁移方式,物理备 ...
- 【JDBC第8章】数据库连接池
第8章:数据库连接池 8.1 JDBC数据库连接池的必要性 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤: 在主程序(如servlet.beans)中建立数据库连接 进行sql操作 ...
- HTB打靶记录-EscapeTwo
信息收集 nmap -sV -sC -O 10.10.11.51 Starting Nmap 7.95 ( https://nmap.org ) at 2025-04-05 14:52 CST Sta ...
- 『Plotly实战指南』--箱线图绘制与应用
在数据可视化领域,箱线图(Box Plot)是一种强大的工具,用于展示数据的分布特征.集中趋势以及异常值. 它不仅能够快速揭示数据的偏态.离散程度,还能帮助我们识别潜在的数据问题. 本文将从基础绘制到 ...
- React AntD的Dropdown组件报错:React.Children.only expected to receive a single React element child.可能的n原因
React.Children.only expected to receive a single React element child. Error: React.Children.only exp ...
- OneNote Embedded 文件滥用检测
本文分享自天翼云开发者社区<OneNote Embedded 文件滥用检测>,作者:Icecream 攻击技术 在这些网络钓鱼活动中被滥用的OneNote功能是在图片后面隐藏嵌入式文件,诱 ...
- 【命令详解001】top
top命令可以用于实时监控cpu的状态,显示系统中各个进程的资源占用情况. 本次来详细看下top命令. 常用命令示例: top # 对,无参数的top命令是最长用的资源监控命令. [root@VM_0 ...
- 零基础搭建AI作曲工具:基于Magenta/TensorFlow的交互式音乐生成系统
引言:当AI遇见莫扎特 "音乐是流动的建筑",当人工智能开始理解音符间的数学规律,音乐创作正经历着前所未有的范式变革.本文将手把手教你构建一套智能作曲系统,不仅能够生成古典钢琴小品 ...
- Python 潮流周刊#101:Rust 开发的 Python 类型检查工具(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- Flutter开发的高效图片压缩工具:让APP更加丝滑
@charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...