ES分词器

发布于 2022-09-05  8.16k 次阅读


1.Analysis和Analyzer

Analysis:文本分析是把全文转换一系列单词(term/token)的过程,也叫分词(Analyzer)。Analysis是通过Analyzer来实现的,分词就是将文档通过Analyzer分成一个一个的Term(关键词查询),每一个Term都指向包含这个Term的文档

分析器(Analyzer)由三部分组成:

  • character filters 字符过滤器
  • tokenizers 分词器
  • token filters Token过滤器

① character filters 字符过滤器

  • 在一段文本进行分词之前,先进行预处理,比如说最常见的就是过滤html标签

如:<span>hello</span> --> hello  

② tokenizers 分词器

  • 英文分词可以根据空格将单词分开,中文分词比较复杂,可以采用机器学习算法来分词

③ token filters 过滤器

  • 将切分的单词进行加工。大小写转换(例如:"Kafka"转为小写),去掉停用词(例如:the\and\a等等),加入同义词(例如同义词像"jump"和"leap")

注意:

  • 三者的顺序:Character Filters --> Tokenizer --> Token Filter
  • 三者个数:Character Filter(0个或多个) + Tokenizer + Token Filter(0个或者多个)

ES内置分词器:

  • Standard Analyzer:默认分词器,英文按单词切分,并小写处理
  • Simple Analyzer:按照单词切分(符号被过滤),小写处理
  • Stop Analyzer:小写处理,停用词过滤(the,a,is)
  • Whitespace Analyzer:按照空格切分,不转小写
  • Keyword Analyzer:不分词,直接将输入当作输出

2. 内置分词器测试

① 标准(默认)分词器

特点:按照单词分词英文统一转为小写过滤标点符号 中文单字分词

例:

POST /_analyze
{
    "analyzer":"standard",
    "text":"空想家"
}

响应:

{
  "tokens" : [
    {
      "token" : "空",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<IDEOGRAPHIC>",
      "position" : 0
    },
    {
      "token" : "想",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "<IDEOGRAPHIC>",
      "position" : 1
    },
    {
      "token" : "家",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "<IDEOGRAPHIC>",
      "position" : 2
    }
  ]
}

② Simple分词器

特点:按照单词分词 英文统一转为小写 去掉符号 中文不分词

例:

POST /_analyze
{
    "analyzer":"simple",
    "text":"REAL MAN "
}

响应:

{
  "tokens" : [
    {
      "token" : "real",
      "start_offset" : 0,
      "end_offset" : 4,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "man",
      "start_offset" : 5,
      "end_offset" : 8,
      "type" : "word",
      "position" : 1
    }
  ]
}

③ Whitespace分词器

特点:中文,英文按照空格分词 英文不会转为小写 不去掉标点符号

例:

POST /_analyze
{
    "analyzer":"whitespace",
    "text":"空 想家 "
}

响应:

{
  "tokens" : [
    {
      "token" : "空",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "想家",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "word",
      "position" : 1
    }
  ]
}

创建索引时设置分词器

PUT /索引名
{
    "settings":{},
    "mappings":{
          "properties":{
                "字段":{
                    "type":"类型",
                    "analyzer":"分词器"
                }
            } 
        }
    }

3. IK中文分词器

在ES中支持中文分词器非常多,如:smartCN、ik等,推荐使用IK分词器

IK分词器的Github下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases

注:

  • 下载时不要下载Source code包,下载.zip包
  • 版本必须要和ES的版本一致
  • Docker容器运行ES安装插件目录为/usr/share/elasticsearch/plugins

3.1 安装IK分词器

① 上传安装包并解压

unzip elasticsearch-analysis-ik-7.14.0.tar.gz

② 移动到ES的plugins目录中

mv elasticsearch-analysis-ik-7.14.0/ ./elasticsearch-7.14.0/plugins/

重启ES应用,会自动扫描plugins中的插件

3.2 IK的使用

IK有两种颗粒度的拆分:

  • ik_smart:会做最粗粒度的拆分
  • ik_max_word: 将文本做最细粒度的拆分

例: ik_smart拆分

POST /_analyze
{
    "analyzer":"ik_smart",
    "text":"中华人民共和国人民"
}

例:ik_max_word拆分

POST /_analyze
{
    "analyzer":"ik_smart",
    "text":"中华人民共和国人民"
}

3.3 IK拓展词和停用词的配置

IK支持自定义拓展词典和停用词典:

  • 拓展词典:就是有一些词并不是关键词,但是也希望被ES用来作为检索的关键词,可以将这些词加入拓展词典
  • 停用词典:就是有些词是关键词,但是出于业务场景不想使用这些关键词被检索到,可以将这些词放入停用词典

定义拓展词典和停用词典可以修改IK分词器中config目录中IKAnalyzer.cfg.xml这个文件

① 修改vim IkAnalyzer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 -->
        <entry key="ext_dict.dic"></entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords.dic"></entry>
        <!--用户可以在这里配置远程扩展字典 -->
        <!-- <entry key="remote_ext_dict">words_location</entry> -->
        <!--用户可以在这里配置远程扩展停止词字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

② 在ik分词器目录下config目录中创建ext_dict.dic文件,编码一定要是UTF-8才能生效

Vim ext_dict.dic #加入拓展词即可

③ 在ik分词器目录下config目录中创建ext_stopword.dic文件

Vim ext_stopword.dic #加入停用词即可

注:编辑时,一行只能一个词


路漫漫其修远兮,吾将上下而求索