Elasticsearch从入门到放弃:分词器初印象
Elasticsearch 系列回来了,先给因为这个系列关注我的同学说声抱歉,拖了这么久才回来,这个系列虽然叫「Elasticsearch 从入门到放弃」,但只有三篇就放弃还是有点过分的,所以还是回来继续更新。
之前我们聊过了Elasticsearch 的索引和文档,不太熟悉的话可以先翻阅一下前文。今天再一起聊一下 Elasticsearch 的分词器。
关于分词
如果你是讲 Elasticsearch 作为搜索引擎,那么你应该需要对分词进行了解,Elasticsearch 的分词是将全文本转换为一系列单词,这样有助于在搜索时得到相关的结果以及相关性分析。例如我们有一个文本为“I love Elasticsearch”,然后 Elasticsearch 可以将其分解为三个单词,这时我们无论搜索哪个单词,都能搜到这个文本。
Elasticsearch 通过分词器对文本进行分词处理,Elasticsearch 的分词器是由 Character Filters、Tokenizer 和Token Filter 三部分组成。在介绍它们之前,我们先来简单了解一下 Analyze API,它可以帮助我们快速测试一个 Analyzer 的作用,它的用法也非常简单:
GET /_analyze
{
"analyzer" : "standard",
"text" : "Quick Brown Foxes!"
}
其中,analyzer 是指定的分词器,text 是被测试的文本,这样就能得到这个文本分词后的效果。
这是最简单的一种用法,此外,我们还可以在 path 中指定 index,用于测试指定索引中 mapping 设置的 analyzer 或者索引默认的 analyzer。当然,你也可以测试一下自定义的 analyzer,只需要在参数中设置好 Character Filters、Tokenizer 和Token Filter 即可。关于 Analyze API 更多的使用方法可以自行查阅官方文档Analyze API
内置 Analyzer
为了方便使用,Elasticsearch 为我们提供了几种内置 Analyzer:
- Fingerprint:它可以将文本处理为小写的、去除扩展的、有序的、唯一的单词
- Keyword:不分词
- Language:提供了30多种常见语言的分词器
- Pattern:使用正则表达式分词,默认\W+(非字符分隔)
- Simple:按照非字母切分,小写处理
- Standard:默认分词器,会基于 Unicode 文本语法,按照单词划分,并进行小写处理
- Stop:小写处理,过滤停用词(the, a, is)
- Whitespace:按照空格切分,不转小写
现在我们来测试一下 Whitespace Analyzer
GET _analyze
{
"analyzer": "whitespace",
"text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
它的执行结果是
{
"tokens" : [
{
"token" : "The",
"start_offset" : 0,
"end_offset" : 3,
"type" : "word",
"position" : 0
},
{
"token" : "2",
"start_offset" : 4,
"end_offset" : 5,
"type" : "word",
"position" : 1
},
{
"token" : "QUICK",
"start_offset" : 6,
"end_offset" : 11,
"type" : "word",
"position" : 2
},
{
"token" : "Brown-Foxes",
"start_offset" : 12,
"end_offset" : 23,
"type" : "word",
"position" : 3
},
{
"token" : "jumped",
"start_offset" : 24,
"end_offset" : 30,
"type" : "word",
"position" : 4
},
{
"token" : "over",
"start_offset" : 31,
"end_offset" : 35,
"type" : "word",
"position" : 5
},
{
"token" : "the",
"start_offset" : 36,
"end_offset" : 39,
"type" : "word",
"position" : 6
},
{
"token" : "lazy",
"start_offset" : 40,
"end_offset" : 44,
"type" : "word",
"position" : 7
},
{
"token" : "dog's",
"start_offset" : 45,
"end_offset" : 50,
"type" : "word",
"position" : 8
},
{
"token" : "bone.",
"start_offset" : 51,
"end_offset" : 56,
"type" : "word",
"position" : 9
}
]
}
如果有兴趣,可以自行测试一下其他的内置 Analyzer。除了内置的 Analyzer 之外,你也可以根据需要自定义分词器。
下面我们来看怎么定义我们需要的 Analyzer。
前面提到 Analyzer 由三部分组成,其中 Character Filters 用于对原始文本进行处理(例如去掉html标签),Tokenizer 是按照指定规则进行切分,Token Filter 负责将切分的单词进行加工(例如转小写)。
Character Filters
Character Filters 是分词的第一步,Elasticsearch 用它来对原始文本进行一些处理。内置的 Character Filters 有三个,分别是:
- HTML strip:使用解码值替换HTML标签
- Mapping:使用指定的替换项替换指定的字符串
- Pattern replace:使用指定的替换项替换正则匹配的字符串
HTML strip 默认会替换文本中所有的 HTML 标签,你也可以通过设置escaped_tags,将一些特定的标签排除
PUT my_index
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "keyword",
"char_filter": [
"my_custom_html_strip_char_filter"
]
}
},
"char_filter": {
"my_custom_html_strip_char_filter": {
"type": "html_strip",
"escaped_tags": [
"b"
]
}
}
}
}
}
这个自定义 Analyzer 就不会替换标签 b。
Tokenizer
在对原始文本进行初步的处理之后,Tokenizer 就要上场了,它帮助我们根据指定的规则进行分词,Elasticsearch 同样提供了一些内置的 Tokenizer。
- Character group:按照配置的字符组进行切分
- Classic:针对英语语法进行分词
- Edge n-gram:从单词的起始字符开始按长度依次切分quick 会被分为[q, qu, qui, quic, quick]
- Keyword:不切分
- Letter:遇到非字母的字符进行切分
- Lowercase:与类似 Letter 类似,不过它会把切分后的单词转为小写
- N-gram:把单词切分为指定长度的字符串集合,quick 会被分为[qu, ui, ic, ck]
- Path hierarchy:对路径进行切分,/foo/bar/baz 会分为[/foo, /foo/bar, /foo/bar/baz]
- Pattern:根据正则匹配进行切分
- Simple pattern:正则会受到一些限制,但不支持按照匹配到的分割符切分
- Simple pattern split:是支持按照匹配到的分割符切分的Simple pattern
- Standard:按照单词进行切分
- Thai:针对泰语进行切分
- UAX URL email:与 Standard 相似,但它会把 url 或邮箱当作一个整体
- Whitespace:按照空格进行切分
在这里你可以先对这些内置的 Tokenizer 有个初步的了解,知道它们能干什么,在具体使用的时候可以查阅官方文档进行更详细的了解,很多 Tokenizer 还支持一些参数配置,这些到实际场景中灵活使用就好。
Token Filter
Elasticsearch 内置的 Token Filter 非常多,这里列几个常用的吧:
- Trim:删除前后空格
- Uppercase:转大写
- Lowercase:转小写
- Stop:停用词过滤
- ……
Elasticsearch 中内置的这些分词器及组件可以满足我们日常的大部分需求了,能够做到灵活应用就很厉害了。如果真的遇到解决不了的问题,你也可以尝试自定义分词器,例如对我们的中文进行分词。
中文分词
中文分词的难点在于,它不像英文那样有天然的空格可以进行切分,我们也不能简单的把它分成一个个的字,而是要分成有意义的词。
比较不错的中文分词器有 ICU Analyzer、IK 和 THULAC
ICU Analyzer
ICU Analyzer 并不是 Elasticsearch 内置的分词器,所以我们需要预先安装插件才能使用
执行命令
elasticsearch-plugin install analysis-icu
进行安装,安装好以后可以使用命令elasticsearch-plugin list
进行查看。
安装好之后就可以运行下面这个例子
GET _analyze
{
"analyzer": "standard",
"text": "觉得好看就点赞"
}
GET _analyze
{
"analyzer": "icu_analyzer",
"text": "觉得好看就点赞"
}
你会发现 standard analyzer 就是把这句话拆成一个个字,而 icu analyzer 基本会根据语义进行拆分。
总结
经过本文的介绍,相信你对 Elasticsearch 的分词器也有了一个初步的认识,知道它由什么组成,能够使用 Analyze API 对一个分词器进行简单的测试,也基本能够自定义一些分词器了。
我对内置的 Token Filter 介绍的比较少,你可以结合官方文档,对你感兴趣的 Token Filter 进行更深入的研究,如果有什么问题也欢迎和我讨论。
Elasticsearch从入门到放弃:分词器初印象的更多相关文章
- ElasticSearch搜索引擎安装配置中文分词器IK插件
近几篇ElasticSearch系列: 1.阿里云服务器Linux系统安装配置ElasticSearch搜索引擎 2.Linux系统中ElasticSearch搜索引擎安装配置Head插件 3.Ela ...
- 使用Docker 安装Elasticsearch、Elasticsearch-head、IK分词器 和使用
原文:使用Docker 安装Elasticsearch.Elasticsearch-head.IK分词器 和使用 Elasticsearch的安装 一.elasticsearch的安装 1.镜像拉取 ...
- Elasticsearch笔记六之中文分词器及自定义分词器
中文分词器 在lunix下执行下列命令,可以看到本来应该按照中文"北京大学"来查询结果es将其分拆为"北","京","大" ...
- elasticsearch插件安装之--中文分词器 ik 安装
/** * 系统环境: vm12 下的centos 7.2 * 当前安装版本: elasticsearch-2.4.0.tar.gz */ ElasticSearch中内置了许多分词器, standa ...
- ElasticSearch速学 - IK中文分词器远程字典设置
前面已经对”IK中文分词器“有了简单的了解: 但是可以发现不是对所有的词都能很好的区分,比如: 逼格这个词就没有分出来. 词库 实际上IK分词器也是根据一些词库来进行分词的,我们可以丰富这个词库. ...
- Elasticsearch集群使用ik分词器
IK分词插件的安装 ES集群环境 VMWare下三台虚拟机Ubuntu 14.04.2 LTS JDK 1.8.0_66 Elasticsearch 2.3.1 elasticsearch-jdbc- ...
- Elasticsearch从入门到放弃:索引基本使用方法
前文我们提到,Elasticsearch的数据都存储在索引中,也就是说,索引相当于是MySQL中的数据库.是最基础的概念.今天分享的也是关于索引的一些常用的操作. 创建索引 curl -X PUT & ...
- Elasticsearch系列---倒排索引原理与分词器
概要 本篇主要讲解倒排索引的基本原理以及ES常用的几种分词器介绍. 倒排索引的建立过程 倒排索引是搜索引擎中常见的索引方法,用来存储在全文搜索下某个单词在一个文档中存储位置的映射.通过倒排索引,我们输 ...
- Elasticsearch从入门到放弃:瞎说Mapping
前面我们聊了 Elasticsearch 的索引.搜索和分词器,今天再来聊另一个基础内容-- Mapping. Mapping 在 Elasticsearch 中的地位相当于关系型数据库中的 sche ...
随机推荐
- MethodHandle(方法句柄)系列之二:方法句柄的简单使用
二话不说,上代码 /** * * @author LiuYeFeng<897908343@qq.com> * @date 2015年4月8日 下午10:41:13 * @CopyRigh ...
- Linux (五) VIM编辑器
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.简介 Linux系统环境下的一款非常重要的文本编辑工具,我们在Linux环境下几乎所有的文本文件 ...
- PriorityBlockingQueue 和 Executors.newCachedThreadPool()
1.PriorityBlockingQueue里面存储的对象必须是实现Comparable接口. 2.队列通过这个接口的compare方法确定对象的优先级priority. 规则是:当前和其他对象比较 ...
- ASP.NET MVC 数据传递进阶 从数据库拿到数据后的三种方式
目录 回顾 数据 显示 因为这个小练习有EF的一些东西,我们来回顾一下. 一.回顾 回顾一点EF的知识怎么生成数据库模型. 1.首先我们在Models文件夹右键添加新建项,在数据分栏下有ADO.NET ...
- Java实现 蓝桥杯VIP 基础练习 Sine之舞
问题描述 最近FJ为他的奶牛们开设了数学分析课,FJ知道若要学好这门课,必须有一个好的三角函数基本功.所以他准备和奶牛们做一个"Sine之舞"的游戏,寓教于乐,提高奶牛们的计算能力 ...
- Java实现 LeetCode 322 零钱兑换
322. 零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总金额,返回 -1. 示例 1: 输 ...
- Java实现 LeetCode 173 二叉搜索树迭代器
173. 二叉搜索树迭代器 实现一个二叉搜索树迭代器.你将使用二叉搜索树的根节点初始化迭代器. 调用 next() 将返回二叉搜索树中的下一个最小的数. 示例: BSTIterator iterato ...
- Java实现 洛谷 P2118 比例简化
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
- 获取ip地址,并根据ip获取当前省份
<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> //methods里面 // 获取 ...
- Linux: 如何分割文件,不再被 4G 大小限制了
单文件 4G 限制 FAT32 4G 限制 百度网盘超出 4G 限制 单文件分割与合并 单文件,如:archive.tar.gz 分割 split -b 3000M -d -a 1 archive.t ...