IMPORTANT: This documentation is no longer updated. Refer to Elastic's version policy and the latest documentation.

Hunspell 词干提取器

edit

Elasticsearch 提供了基于词典提取词干的 hunspell 语汇单元过滤器(token filter). Hunspell hunspell.github.io 是一个 Open Office、LibreOffice、Chrome、Firefox、Thunderbird 等众多其它开源项目都在使用的拼写检查器。

可以从这里获取 Hunspell 词典 :

一个 Hunspell 词典由两个文件组成 — 具有相同的文件名和两个不同的后缀 — 如 en_US—和下面的两个后缀的其中一个:

.dic
包含所有词根,采用字母顺序,再加上一个代表所有可能前缀和后缀的代码表 【集体称之为词缀( affixes
.aff
包含实际 .dic 文件每一行代码表对应的前缀和后缀转换

安装一个词典

edit

Hunspell 语汇单元过滤器在特定的 Hunspell 目录里寻找词典, 默认目录是 ./config/hunspell/.dic 文件和 .aff 文件应该要以子目录且按语言/区域的方式来命名。 例如,我们可以为美式英语创建一个 Hunspell 词干提取器,目录结构如下:

config/
  └ hunspell/ 
      └ en_US/ 
          ├ en_US.dic
          ├ en_US.aff
          └ settings.yml 

Hunspell 目录位置可以通过编辑 config/elasticsearch.yml 文件的: indices.analysis.hunspell.dictionary.location 设置来修改。

en_US 是这个区域的名字,也是我们传给 hunspell 语汇单元过滤器参数 language 值。

一个语言一个设置文件,下面的章节会具体介绍。

按语言设置

edit

在语言的目录设置文件 settings.yml 包含适用于所有字典内的语言目录的设置选项。

---
ignore_case:          true
strict_affix_parsing: true

这些选项的意思如下:

ignore_case

Hunspell 目录默认是区分大小写的,如,姓氏 Booker 和名词 booker 是不同的词,所以应该分别进行词干提取。 也许让 hunspell 提取器区分大小写是一个好主意,不过也可能让事情变得复杂:

  • 一个句子的第一个词可能会被大写,因此感觉上会像是一个名词。
  • 输入的文本可能全是大写,如果这样那几乎一个词都找不到。
  • 用户也许会用小写来搜索名字,在这种情况下,大写开头的词将找不到。

一般来说,设置参数 ignore_casetrue 是一个好主意。

strict_affix_parsing
词典的质量千差万别。 一些网上的词典的 .aff 文件有很多畸形的规则。 默认情况下,如果 Lucene 不能正常解析一个词缀(affix)规则, 它会抛出一个异常。 你可以通过设置 strict_affix_parsingfalse 来告诉 Lucene 忽略错误的规则。

创建一个 Hunspell 语汇单元过滤器

edit

一旦你在所有节点上安装好了词典,你就能像这样定义一个 hunspell 语汇单元过滤器:

PUT /my_index
{
  "settings": {
    "analysis": {
      "filter": {
        "en_US": {
          "type":     "hunspell",
          "language": "en_US" 
        }
      },
      "analyzer": {
        "en_US": {
          "tokenizer":  "standard",
          "filter":   [ "lowercase", "en_US" ]
        }
      }
    }
  }
}

参数 language 和目录下对应的名称相同。

你可以通过 analyze API 来测试这个新的分析器, 然后和 english 分析器比较一下它们的输出:

GET /my_index/_analyze?analyzer=en_US 
reorganizes

GET /_analyze?analyzer=english 
reorganizes

返回 organize

返回 reorgan

在前面的例子中,hunspell 提取器有一个有意思的事情,它不仅能移除前缀还能移除后缀。大多数算法词干提取仅能移除后缀。

Hunspell 词典会占用几兆的内存。幸运的是,Elasticsearch 每个节点只会创建一个词典的单例。 所有的分片都会使用这个相同的 Hunspell 分析器。

Hunspell 词典格式

edit

尽管使用 hunspell 不必了解 Hunspell 词典的格式, 不过了解格式可以帮助我们编写自己的自定义的词典。其实很简单。

例如,在美式英语词典(US English dictionary),en_US.dic 文件包含了一个包含词 analyze 的实体,看起来如下:

analyze/ADSG

en_US.aff 文件包含了一个针对标记 AGDS 的前后缀的规则。 其中应该只有一个能匹配,每一个规则的格式如下:

[type] [flag] [letters to remove] [letters to add] [condition]

例如,下面的后缀 (SFX) 规则 D 。它是说,当一个词由一个辅音 (除了 aeiou 外的任意音节) 后接一个 y ,那么它可以移除 y 和添加 ied 结尾 (如,readyreadied )。

SFX    D      y   ied  [^aeiou]y

前面提到的 AGDS 标记对应规则如下:

SFX D Y 4
SFX D   0     d          e 
SFX D   y     ied        [^aeiou]y
SFX D   0     ed         [^ey]
SFX D   0     ed         [aeiou]y

SFX S Y 4
SFX S   y     ies        [^aeiou]y
SFX S   0     s          [aeiou]y
SFX S   0     es         [sxzh]
SFX S   0     s          [^sxzhy] 

SFX G Y 2
SFX G   e     ing        e 
SFX G   0     ing        [^e]

PFX A Y 1
PFX A   0     re         . 

analyze 以一个 e 结尾,所以它可以添加一个 d 变成 analyzed

analyze 不是由 sxzhy 结尾,所以,它可以添加一个 s 变成 analyzes

analyze 以一个 e 结尾,所以,它可以移除 e 和添加 ing 然后变成 analyzing

可以添加前缀 re 来形成 reanalyze 。这个规则可以组合后缀规则一起形成: reanalyzesreanalyzedreanalyzing

了解更多关于 Hunspell 的语法,可以前往 Hunspell 文档