ElasticSearch笔记-分析器
文本分析器(Text analysis)
在ES当中,只有text类型的字段才会用到全文索引。
我们在建立索引和搜索时,都会用的分析器。
分析器使ES支持全文索引,搜索的结果是和你搜索的内容相关的,而不是你搜索内容的确切匹配。
分析器之所以能够使搜索支持全文索引,都是因为有分词器(tokenization),它可以将一句话、一篇文章切分成不同的词语,每个词语都是独立的。
分析器除了要做分词,还要做归一化(Normalization)。如匹配大小写不同的词、复数形式的词、同义词。为了解决这些问题,分析器要把这些分词归一化到标准的格式。这样我们在搜索的时候就不用严格的匹配了,相似的词语我们也能够检索出来。
分析器的组成
分析器,无论是内置的,还是自定义的,都是由3部分组成:字符过滤器(character filters)、分词器(tokenizers)、分词过滤器(token filters)。
字符过滤器
字符过滤器接收最原始的文档,并且可以修改和删除其内容,比如:可以把中文的一二三四五六七八九,变成阿拉伯数字123456789。它还可以过滤html标签,并对其进行转义。还可以通过正则表达式,把匹配到的内容转化成其他的内容。一个分析器可以有多个字符过滤器,也可以没有字符过滤器。
分词器
一个分析器只能有一个确定的分词器,它可以把一句话分成若干个词
分词过滤器
分词过滤器接收分词并且可以改变分词,比如:小写分词过滤器,它将接收到的分词全部转换成小写。助词过滤器,它将删除掉一些公共的助词,比如英语里的 the,is,are等,中文里的的,得等。同义词过滤器,它将在你的分词中,添加相应的同义词。一个分析器可以有多个分词过滤器,它们将按顺序执行。
分析器组件调用顺序:字符过滤器 -> 分词器 -> 词项过滤器
ES内置分析器
Standard Analyzer
默认分词器,根据Unicode联盟定义的单词边界划分文本,支持多语言,小写处理
组成:
(1)Tokenizer:Standard Tokenizer
(2)Token Filters:Lower Case Token Filter
例:POST _analyze
{
"analyzer": "standard",
"text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
上面的句子会产生下面的条件:
[ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog's, bone ]
Simple Analyzer
在任何不是字母的地方分隔文本,小写处理
组成:
(1)Tokenizer:Lower Case Tokenizer
POST _analyze
{
"analyzer": "simple",
"text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
上面的句子会产生下面的条件:
[ the, quick, brown, foxes, jumped, over, the, lazy, dog, s, bone ]
Whitespace Analyzer
空白字符作为分隔符,不转小写。
组成:
(1)Tokenizer:Whitespace Tokenizer
例:
POST _analyze
{
"analyzer": "whitespace",
"text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
上面的句子会产生下面的条件:
[ The, 2, QUICK, Brown-Foxes, jumped, over, the, lazy, dog's, bone. ]
Stop Analyzer
类似于Simple Analyzer,但相比Simple Analyzer,支持删除停止字
停用词指语气助词等修饰性词语,如the, an, 的, 这等
组成 :
(1)Tokenizer:Lower Case Tokenizer
(2)Token Filters:Stop Token Filter
例:
POST _analyze
{
"analyzer": "stop",
"text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
上面的句子会产生下面的条件:
[ quick, brown, foxes, jumped, over, lazy, dog, s, bone ]
Keyword Analyzer
不分词,直接将输入作为一个单词输出,它接受给定的任何文本,并输出与单个术语完全相同的文本。
组成:
(1)Tokenizer:Keyword Tokenizer
例:
POST _analyze
{
"analyzer": "keyword",
"text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
上面的句子会产生下面的条件:
[ The 2 QUICK Brown-Foxes jumped over the lazy dog's bone. ]
pattern Analyzer
模式分词器使用正则表达式将文本拆分为术语。
通过正则表达式自定义分隔符,默认是\W+,即非字词的符号作为分隔符
Language Analyzer
提供30多种常见语言的分词器
中文分析器
IK(推荐)、jieba、THULAC
英文我们可以按照空格将一句话、一篇文章进行分词,然后对分词进行过滤,最后留下有意义的词。中文的一句话是没有空格的,这就要有一个强大的中文词库,当你的内容中出现这个词时,就会将这个词提炼出来。
查看分词器的分词结果(ik分词器有两种ik_smart、ik_max_word):
GET /_analyze
{
"analyzer": "ik_max_word",
"text": ["我是中国人你是美国人content内容123 "]
}
IK中文分词器的安装
ES默认是没有IK中文分词器的,我们要将IK中文分词器作为一个插件安装到ES中,安装的步骤也很简单:
-
从GitHub上下载适合自己ES版本的IK中文分词器,地址如下:https://github.com/medcl/elasticsearch-analysis-ik/releases。
-
切换到ES的插件目录中(${ES_HOME}/plugins)
cd plugins -
创建ik目录
mkdir ik -
下载IK分析器
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.6.2/elasticsearch-analysis-ik-7.6.2.zip -
解压。
unzip elasticsearch-analysis-ik-7.6.2.zip -
重启ES容器。
步骤如下:
wget
IK中文分词器初探
IK中文分词器插件给我们提供了两个分析器
- ik_max_word: 会将文本做最细粒度的拆分
- ik_smart:会做最粗粒度的拆分
IK词库热更新
打开配置文件/plugins/ik/config/IKAnalyzer.cfg.xml
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict"></entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords"></entry>
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
通过remote_ext_dict配置扩展词URL;通过remote_ext_stopwords配置停止词URL
http请求需要返回两个header,Last-Modified和ETag,都是字符串类型,只要其中一个发生变化,该插件就会抓取新的分词,进而更新词库。
返回的内容格式是一行一个分词,换行符用\n
即可。
满足上面两点要求就可以实现热更新分词,不需要重启ES实例
测试分析器
ES有分析器的api,我们指定分析器和文本内容,就可以得到分词的结果
指定空格分析器
POST _analyze
{
"analyzer": "whitespace",
"text": "中华 人 民 共 和 国"
}
指定分词器、过滤器
除了指定分析器,我们也可以指定分词器、过滤器
POST _analyze
{
"tokenizer": "standard",
"filter": [ "lowercase", "asciifolding" ],
"text": "Is this déja vu?"
}
指定了标准的分词器,小写过滤器和asciifolding过滤器
配置文本分析器
ES默认给我们配置的分析器是Standard Analyzer。如果标准的分析器不适合你,你可以指定其他的分析器,或者自定义一个分析器。
为指定的字段配置分析器
我们在创建映射时,可以为每一个text类型的字段指定分析器
PUT my_index
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "whitespace"
}
}
}
}
为索引指定默认的分析器
如果我们觉得为每一个字段指定分析器过于麻烦,我们还可以为索引指定一个默认的分析器
PUT my_index
{
"settings": {
"analysis": {
"analyzer": {
"default": {
"type": "whitespace"
}
}
}
}
}
自定义分析器
PUT /my_index
{ "settings": {
"analysis": {
"char_filter": { //字符过滤器
"&_to_and": {
"type": "mapping",
"mappings": [ "&=> and "] //把&替换为 " and "
}
},
"tokenizer": { ... custom tokenizers ... },
"filter": {
"my_stopwords": { //词单元过滤器
"type": "stop",
"stopwords": [ "the", "a" ] //移除自定义的停止词
}
},
"analyzer": { //分析器定义
"my_analyzer": {
"type": "custom",
"char_filter": [ "html_strip", "&_to_and" ],
"tokenizer": "standard",
"filter": [ "lowercase", "my_stopwords" ]
}
}
}
}
}
参考:
https://www.cnblogs.com/boboooo/p/12836770.html
https://www.cnblogs.com/boboooo/p/12843578.html