文章目录

  • 1. 什么是analysis?
  • 2. 主要组成
  • 3. 使用分析器
    • 3.1 Elasticsearch的内置分析器
    • 3.2 分析器测试
    • 3.3 自定义分析器
  • 4. 分析器作用位置及使用
    • 4.1 创建索引时指定分析器
    • 4.2 搜索时如何确定分析器
  • 5. 常用分析器
    • 5.1 繁简转换分析器
      • 5.1.1 安装与验证
      • 5.1.2 插件介绍
      • 5.1.3 简转繁
      • 5.1.4 繁转简
    • 5.2 Ik分析器
      • 5.2.1 安装与验证
      • 5.2.2 插件介绍
      • 5.2.3 基本使用
      • 5.2.4 自定义分词库
    • 5.3 同义词分析器
    • 5.4 拼音分析器

1. 什么是analysis?

analysis是Elasticsearch在文档发送之前对文档正文执行的过程,以添加到反向索引中(inverted index)。 在将文档添加到索引之前,Elasticsearch会为每个分析的字段执行许多步骤:

  • Character filtering (字符过滤器): 使用字符过滤器转换字符
  • Breaking text into tokens (把文字转化为标记): 将文本分成一组一个或多个标记
  • Token filtering:使用标记过滤器转换每个标记(大小写转化/删除无用词等等)
  • Token indexing:把这些标记存于index中

文本分词会发生在两个地方:

  • 创建索引:当索引文档字符类型为text时,在建立索引时将会对该字段进行分词。
  • 搜索:当对一个text类型的字段进行全文检索时,会对用户输入的文本进行分词。

2. 主要组成

总体说来一个analyzer可以分为如下的几个部分:

  • 0个或1个以上的character filter

    接收原字符流,通过添加、删除或者替换操作改变原字符流。例如:去除文本中的html标签,或者将罗马数字转换成阿拉伯数字等。一个字符过滤器可以有零个或者多个。

  • 1个tokenizer

    简单的说就是将一整段文本拆分成一个个的词。例如拆分英文,通过空格能将句子拆分成一个个的词,但是对于中文来说,无法使用这种方式来实现。在一个分词器中,有且只有一个tokenizeer

  • 0个或1个以上的token filter

    将切分的单词添加、删除或者改变。例如将所有英文单词小写,或者将英文中的停词a删除等。在token filters中,不允许将token(分出的词)的position或者offset改变。同时,在一个分词器中,可以有零个或者多个token filters.

    单词的过滤顺序按照 filter过滤器的顺序

3. 使用分析器

默认ES使用standard analyzer

3.1 Elasticsearch的内置分析器

Analyzer

  • Standard Analyzer - 默认分词器,按词切分,小写处理
  • Simple Analyzer - 按照非字母切分(符号被过滤), 小写处理
  • Stop Analyzer - 小写处理,停用词过滤(the,a,is)
  • Whitespace Analyzer - 按照空格切分,不转小写
  • Keyword Analyzer - 不分词,直接将输入当作输出
  • Patter Analyzer - 正则表达式,默认\W+(非字符分割)
  • Language - 提供了30多种常见语言的分词器
  • Customer Analyzer 自定义分词器

参考链接

Character Filter

character filter logical name description
mapping char filter mapping 根据配置的映射关系替换字符
html strip char filter html_strip 去掉HTML元素
pattern replace char filter pattern_replace 用正则表达式处理字符串

Tokenizer

tokenizer logical name description
standard tokenizer standard
edge ngram tokenizer edgeNGram
keyword tokenizer keyword 不分词
letter analyzer letter 按单词分
lowercase analyzer lowercase letter tokenizer, lower case filter
ngram analyzers nGram
whitespace analyzer whitespace 以空格为分隔符拆分
pattern analyzer pattern 定义分隔符的正则表达式
uax email url analyzer uax_url_email 不拆分 url 和 email
path hierarchy analyzer path_hierarchy 处理类似 /path/to/somthing样式的字符串

Token Filter

token filter logical name description
standard filter standard
ascii folding filter asciifolding
length filter length 去掉太长或者太短的
lowercase filter lowercase 转成小写
ngram filter nGram
edge ngram filter edgeNGram
porter stem filter porterStem 波特词干算法
shingle filter shingle 定义分隔符的正则表达式
stop filter stop 移除 stop words
word delimiter filter word_delimiter 将一个单词再拆成子分词
stemmer token filter stemmer
stemmer override filter stemmer_override
keyword marker filter keyword_marker
keyword repeat filter keyword_repeat
kstem filter kstem
snowball filter snowball
phonetic filter phonetic 插件
synonym filter synonyms 处理同义词
compound word filter dictionary_decompounder, hyphenation_decompounder 分解复合词
reverse filter reverse 反转字符串
elision filter elision 去掉缩略语
truncate filter truncate 截断字符串
unique filter unique
pattern capture filter pattern_capture
pattern replace filte pattern_replace 用正则表达式替换
trim filter trim 去掉空格
limit token count filter limit 限制 token 数量
hunspell filter hunspell 拼写检查
common grams filter common_grams
normalization filter arabic_normalization, persian_normalization

内置 Analyzer 一览表

3.2 分析器测试

可以通过_analyzerAPI来测试分词的效果。

POST _analyze
{"analyzer": "standard","text": "The quick Brown Fox"
}

结果: 按空格切分,所以会有四个词

可以按照下面的规则组合使用:

  • 0个或者多个character filters
  • 一个tokenizer
  • 0个或者多个token filters
POST _analyze
{"tokenizer": "standard","filter": ["lowercase"],"text": "The quick Brown Fox"
}

结果: 按空格切分,所以会有四个词,但每个词都是小写

3.3 自定义分析器

当内置的分词器无法满足需求时,可以创建custom类型的分词器。

  • tokenizer:内置或定制的tokenizer.(必须)
  • char_filter:内置或定制的char_filter(非必须)
  • filter:内置或定制的token filter(非必须)
  • position_increment_gap:当值为文本数组时,设置改值会在文本的中间插入假空隙。设置该属性,对与后面的查询会有影响。默认该值为100.
PUT my_index
{"settings": {"analysis": {"analyzer": {"my_custom_analyzer":{"type":"custom","tokenizer":"standard","char_filter":["html_strip"],"filter":["lowercase","asciifolding"]}}}}
}

上面的示例中定义了一个名为my_custom_analyzer的分析器,该分析器的typecustomtokenizerstandardchar_filterhmtl_strip,filter定义了两个分别为:lowercaseasciifolding.

测试一下:

POST my_index/_analyze
{"text": "Is this <b>déjà vu</b>?","analyzer": "my_custom_analyzer"
}

结果:

{"tokens" : [{"token" : "is","start_offset" : 0,"end_offset" : 2,"type" : "<ALPHANUM>","position" : 0},{"token" : "this","start_offset" : 3,"end_offset" : 7,"type" : "<ALPHANUM>","position" : 1},{"token" : "deja","start_offset" : 11,"end_offset" : 15,"type" : "<ALPHANUM>","position" : 2},{"token" : "vu","start_offset" : 16,"end_offset" : 22,"type" : "<ALPHANUM>","position" : 3}]
}

4. 分析器作用位置及使用

分析器的使用地方有两个:

  • 创建索引时
  • 进行搜索时

4.1 创建索引时指定分析器

如果设置手动设置了分析器,ES将按照下面顺序来确定使用哪个分析器:

  • 先判断字段是否有设置分析器,如果有,则使用字段属性上的分析器设置
  • 如果设置了analysis.analyzer.default,则使用该设置的分析器
  • 如果上面两个都未设置,则使用默认的standard分析器

为字段指定分析器

PUT my_index
{"mappings": {"properties": {"title":{"type":"text","analyzer": "whitespace"}}}
}

设置索引默认分析器

PUT my_index
{"settings": {"analysis": {"analyzer": {"default":{"type":"simple"}}}}
}

4.2 搜索时如何确定分析器

在搜索时,通过下面参数依次检查搜索时使用的分词器:

  • 搜索时指定analyzer参数
  • 创建mapping时指定字段的search_analyzer属性
  • 创建索引时指定settinganalysis.analyzer.default_search
  • 查看创建索引时字段指定的analyzer属性
  • 如果上面几种都未设置,则使用默认的standard分词器。

搜索时指定analyzer查询参数

GET my_index/_search
{"query": {"match": {"message": {"query": "Quick foxes","analyzer": "stop"}}}
}

指定字段的seach_analyzer

PUT my_index
{"mappings": {"properties": {"title":{"type":"text","analyzer": "whitespace","search_analyzer": "simple"}}}
}
//  上面指定创建索引时使用的默认分析器为whitespace分词器,而搜索的默认分词器为 simple分词器。

指定索引的默认搜索分词器

PUT my_index
{"settings": {"analysis": {"analyzer": {"default":{"type":"simple"},"default_seach":{"type":"whitespace"}}}}
}
// 上面指定创建索引时使用的默认分词器为simple分词器,而搜索的默认分词器为whitespace分词器。

5. 常用分析器

5.1 繁简转换分析器

简体和繁体的几个主要情况: