Elasticsearch-Analyzer分词器详解

537 阅读2分钟

我正在参加「掘金·启航计划」

一、Analysis与Analyzer

  • Analysis文本分析,是把全文本转换为一系列单词(term/token)的过程,也叫分词
  • Analysis是通过Analyzer来实现的
    • 可以使用Elasticsearch内置的分析器/或者按需求定制化分析器
  • 除了在数据写入时转换词条,匹配Query语句时候也需要用相同的分析器对应查询语句进行分析

二、Analyzer的组成

通常Analyzer由三个部分组成。

  • Character Filters:针对原始文本处理,例如去除html标签等。

  • Tokenizer:按照一定的规则,对字符串进行切分单词。

  • Token Filter:将切分的单词进行加工、大小写转换、删除stopwords、增加同义词等。

三、ES中内置的分词器

  • Standard Analyzer:默认分词器,按词切分,小写处理

  • Simple Analyzer:按照非字母切分(符号被过滤),小写处理

  • Stop Analyzer:小写处理,停用词过滤器(the、a、is等)

  • Whitespace Analyzer:按照空格切分,不转小写

  • Keyword Analyzer:不分词,直接将输入当作输出

  • Patter Analyzer:正则表达式,默认\W+(非字符分割)

  • Language:提供了30多种常见语言的分词器

  • Customer Analyzer:自定义分词器

四、分词器Demo

1.Character Filters 原始文本处理

//使用char filter 进行替换 
POST _analyze
{
  "tokenizer":"standard",
  "char_filter":[
    {
      "type":"mapping",
      "mappings":["- => _"]
    }
    ],
    "text":"123-456,I-liu,test-love,test-990"
}

//char filter 替换表情符号
POST _analyze
{
  "tokenizer": "standard",
  "char_filter": [
    {
      "type":"mapping",
      "mappings":[":) => happy",":( => sad"]
    }],
    "text": ["I am felling :)", "Delele :("]
}

//正则表达式
GET _analyze
{
  "tokenizer": "standard",
  "char_filter":[
    {
      "type":"pattern_replace",
      "pattern":"http://(.*)",
      "replacement":"$1"
    }
    ],
    "text": "http://www.baidu.com"
}

2.使用standard analyzer API

POST _analyze
{
  "tokenizer": "standard",
  "text": "I love you"
}

standard 是es 自带默认的分词器,标准分词器提供基于语法的分词(基于 Unicode 文本分割算法),并且适用于大多数语言。

特点:

  • 默认分词器
  • 按词切分: 按单个词汇分割
  • 小写处理:Lower case 是打开的 (如过写成: "tokenizer": "standard",则不会小写处理)
  • stop默认关闭

text是我们要分词的文本

{
  "tokens": [
    {
      "token": "i",
      "start_offset": 0,
      "end_offset": 1,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "love",
      "start_offset": 2,
      "end_offset": 6,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "you",
      "start_offset": 7,
      "end_offset": 10,
      "type": "<ALPHANUM>",
      "position": 2
    }
  ]
}

3、Simple Analyzer

按照非字母切分(符号被过滤),小写处理

POST _analyze
{
  "analyzer": "simple",
  "text": "2 no 3  Http The"
}

下面的结果,可以看到里面的数字应被过滤掉,写的单词也被转成了小写

{
  "tokens": [
    {
      "token": "no",
      "start_offset": 2,
      "end_offset": 4,
      "type": "word",
      "position": 0
    },
    {
      "token": "http",
      "start_offset": 8,
      "end_offset": 12,
      "type": "word",
      "position": 1
    },
    {
      "token": "the",
      "start_offset": 13,
      "end_offset": 16,
      "type": "word",
      "position": 2
    }
  ]
}

4.Whitespace Analyzer 分词器

按照空格分割

GET _analyze
{
  "tokenizer": "whitespace",
  "text":"Happy day 123"
}

看到下面结果是按照空格分割的,但是并没有按照转为小写,如果需要转成小写需要我添加"filter": ["stop"] ,转成小写同时去除the,a等修饰词需要添加 "filter": ["lowercase","stop"]

{
  "tokens": [
    {
      "token": "Happy",
      "start_offset": 0,
      "end_offset": 5,
      "type": "word",
      "position": 0
    },
    {
      "token": "day",
      "start_offset": 6,
      "end_offset": 9,
      "type": "word",
      "position": 1
    },
    {
      "token": "123",
      "start_offset": 10,
      "end_offset": 13,
      "type": "word",
      "position": 2
    }
  ]
}

5.Stop Analyzer

  • 相比Simple Analyzer 多了stop filter, 会把the,a,is等修饰词去除
POST _analyze
{
  "analyzer": "stop",
  "text":"The you are Feeling that life just cannot the be any worse for you,"
}

6.Keyword Analyzer

不分词,直接将输入当一个term输出

//keyword analyzer
POST _analyze
{
  "analyzer": "keyword",
  "text": "hello word"
}

结果:

{
  "tokens": [
    {
      "token": "hello word",
      "start_offset": 0,
      "end_offset": 10,
      "type": "word",
      "position": 0
    }
  ]
}

7.Pattern Analyzer

  • 通过正则表达式进行分割
  • 默认是\w+非字符的符号进行分割
GET _analyze
{
  "analyzer": "pattern",
  "text":"333-444 running Quick brown-foxec leap over lazy dogs"
}
//正则表达式
GET _analyze
{
  "tokenizer": "standard",
  "char_filter":[
    {
      "type":"pattern_replace",
      "pattern":"http://(.*)",
      "replacement":"$1"
    }
    ],
    "text": "http://www.baidu.com"
}

7.Language Analyzer

可以指定不同的语言进行分词,比如English.

GET /_analyze
{
  "analyzer": "english",
  "text":"我爱祖国,Elasticsearch is FUN-fun"
}

结果:

{
  "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": "elasticsearch",
      "start_offset": 5,
      "end_offset": 18,
      "type": "<ALPHANUM>",
      "position": 4
    },
    {
      "token": "fun",
      "start_offset": 22,
      "end_offset": 25,
      "type": "<ALPHANUM>",
      "position": 6
    },
    {
      "token": "fun",
      "start_offset": 26,
      "end_offset": 29,
      "type": "<ALPHANUM>",
      "position": 7
    }
  ]
}

但是对于中文来说,分词器就有了一些特定的难点:

一个句子,要被切分成一个个单词,而不是一个个的字。

在英文中,单词有空格进行分割,中文没有,一句中文在不同的语句里意思不同,比如“他说的确实在理/这事的确定不了”

8. ICU Analyzer

ICU Analyzer 需要安装插件 ---> Elasticserch-plugin install analysis-icu

这个分词插件提供了Unicode的支持,更好的支持亚洲的语言

其他的中文分词器

  • IK
  • THULAC
    • THULAC(THU Lexical Analyzer for Chinese)由清华大学自然语言处理与社会人文计算实验室研制推出的一套中文词法分析工具包,具有中文分词和词性标注功能。
    • github.com/thunlp/THUL…