21

Elasticsearch 分词

 4 years ago
source link: https://foofish.net/elasticsearch-fenci.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

所谓分词就是将一段文本按照语义规则切分成多个词语,当有一篇文章标题是 “马云说996是福报”时,我们需要把这段文本切分成多个词语: 996、马云、福报 等。因为用户搜索的时候可能只会输入一个词语。

之所以要这样做是为了提高搜索的准确度,如果用户搜索的时候输入的关键字是 “996”,刚好能匹配到分词短语 996,就能命中该文本。ES 的搜索不象 MySQL 那样使用 like 语句执行模糊搜索。

搜索的质量取决于分词的好坏。例如 996 如果拆分成9和6,用户输入996又匹配不到,输入9或者6 可能又会搜到很多无关紧要的东西。

分析器

分析器的作用对文本进行分词处理。首先将文本拆分,构建倒排索引,然后对分词进行处理提高分词的搜索准确率。分析器包含3个功能

  • 字符过滤器:将文本中的特殊字符过滤,例如html标签,标点符号
  • 分词器:将文本拆分成单个词条
  • Token 过滤器:对词条进一步优化,单词小写话,删除无用词(的、得、地)等操作

将文档加入索引或者用户搜索的时候都会用到分析器。分析器有很多种,下面将对常用的分析器介绍

空格分析器

空格分析器只适用于英文文本,它按照单词的空格进行切分。因为中文句子是连续的,所以空格分析器不使用。

POST _analyze

{
  "analyzer": "whitespace",
  "text":     "The quick brown fox."
}

# 输出
{
    "tokens": [
        {
            "token": "The",
            "start_offset": 0,
            "end_offset": 3,
            "type": "word",
            "position": 0
        },
        {
            "token": "quick",
            "start_offset": 4,
            "end_offset": 9,
            "type": "word",
            "position": 1
        },
        ...
    ]
}

标准分析器

标准分析器是 Elasticsearch 默认使用的分析器,根据 Unicode 联盟定义的单词边界划分文本,英文按照空格拆分,中文按照单汉字拆分,删除绝大部分标点。

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
        },
        {
            "token": "光",
            "start_offset": 3,
            "end_offset": 4,
            "type": "<IDEOGRAPHIC>",
            "position": 3
        },
        {
            "token": "鲜",
            "start_offset": 4,
            "end_offset": 5,
            "type": "<IDEOGRAPHIC>",
            "position": 4
        },
        {
            "token": "都",
            "start_offset": 6,
            "end_offset": 7,
            "type": "<IDEOGRAPHIC>",
            "position": 5
        },
        ...
    ]
}

给索引指定分析器

创建索引时可指定分析器,加入的文档就会按照这个分词器进行分词保存。

PUT  /account
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_english_analyzer": {
          "type": "standard",
          "max_token_length": 5,
          "stopwords": "_english_"
        }
      }
    }
  }
}

对于已经存在的索引,如何给索引加分析器呢?

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-standard-analyzer.html

IK分析器

标准分析器不适用于中文分词,因为中文只有一个个词语组织在一起才有意义,单个汉字没什么意义,所有就有了专业的中文分析器。

IK 分析器是一款结合了词典和文法分析算法的中文分词组件,基于字符串匹配,支持用户词典扩展定义,支持细粒度和智能切分。

安装插件

使用插件命令安装中文分词IK插件,注意选择ES对应的版本,我这里选择的是7.0

sudo ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.0.0/elasticsearch-analysis-ik-7.0.0.zip

IK分析器的两种分析器分别叫:ik_smart (智能切分), ik_max_word(细粒度)

测试分词

POST /_analyze

{
  "analyzer": "ik_smart",
  "text":     "996都有加班的味道"
}

# 返回
{
    "tokens": [
        {
            "token": "996",
            "start_offset": 0,
            "end_offset": 3,
            "type": "ARABIC",
            "position": 0
        },
        {
            "token": "都有",
            "start_offset": 3,
            "end_offset": 5,
            "type": "CN_WORD",
            "position": 1
        },
        {
            "token": "加班",
            "start_offset": 5,
            "end_offset": 7,
            "type": "CN_WORD",
            "position": 2
        },
        {
            "token": "的",
            "start_offset": 7,
            "end_offset": 8,
            "type": "CN_CHAR",
            "position": 3
        },
        {
            "token": "味道",
            "start_offset": 8,
            "end_offset": 10,
            "type": "CN_WORD",
            "position": 4
        }
    ]
}

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis.html

插件地址:https://github.com/medcl/elasticsearch-analysis-ik/releases

https://github.com/medcl/elasticsearch-analysis-ik/blob/master/README.md

有问题可以扫描二维码和我交流

关注公众号「Python之禅」,回复「1024」免费获取Python资源

vQremuy.jpg!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK