使用停用词

移除停用词的工作是由 stop 停用词过滤器完成的,可以通过创建自定义的分析器来使用它(参见 使用停用词过滤器​{ref}/analysis-stop-tokenfilter.html[stop 停用词过滤器]​)。但是,也有一些自带的分析器预置使用停用词过滤器:

{ref}/analysis-lang-analyzer.html[语言分析器]

  1. 每个语言分析器默认使用与该语言相适的停用词列表,例如:`english` 英语分析器使用 `_english_` 停用词列表。

{ref}/analysis-standard-analyzer.html[standard 标准分析器]

  1. 默认使用空的停用词列表:`_none_` ,实际上是禁用了停用词。

{ref}/analysis-pattern-analyzer.html[pattern 模式分析器]

  1. 默认使用空的停用词列表:为 `_none_` ,与 `standard` 分析器类似。

停用词和标准分析器(Stopwords and the Standard Analyzer)

为了让标准分析器能与自定义停用词表连用,我们要做的只需创建一个分析器的配置好的版本,然后将停用词列表传入:

  1. PUT /my_index
  2. {
  3. "settings": {
  4. "analysis": {
  5. "analyzer": {
  6. "my_analyzer": { (1)
  7. "type": "standard", (2)
  8. "stopwords": [ "and", "the" ] (3)
  9. }
  10. }
  11. }
  12. }
  13. }

<1> 自定义的分析器名称为 my_analyzer

<2> 这个分析器是一个标准 standard 分析器,进行了一些自定义配置。

<3> 过滤掉的停用词包括 andthe

TIP: 任何语言分析器都可以使用相同的方式配置自定义停用词。

保持位置(Maintaining Positions)

analyzer API的输出结果很有趣:

  1. GET /my_index/_analyze?analyzer=my_analyzer
  2. The quick and the dead
  1. {
  2. "tokens": [
  3. {
  4. "token": "quick",
  5. "start_offset": 4,
  6. "end_offset": 9,
  7. "type": "<ALPHANUM>",
  8. "position": 1 (1)
  9. },
  10. {
  11. "token": "dead",
  12. "start_offset": 18,
  13. "end_offset": 22,
  14. "type": "<ALPHANUM>",
  15. "position": 4
  16. }
  17. ]
  18. }

<1> position 标记每个词汇单元的位置。

停用词如我们期望被过滤掉了,但有趣的是两个词项的位置 position 没有变化:quick 是原句子的第二个词,dead 是第五个。这对短语查询十分重要,因为如果每个词项的位置被调整了,一个短语查询 quick dead 会与以上示例中的文档错误匹配。

指定停用词(Specifying Stopwords)

停用词可以以内联的方式传入,就像我们在前面的例子中那样,通过指定数组:

  1. "stopwords": [ "and", "the" ]

特定语言的默认停用词,可以通过使用 _lang_ 符号来指定:

  1. "stopwords": "_english_"

TIP: Elasticsearch 中预定义的与语言相关的停用词列表可以在文档​{ref}/analysis-stop-tokenfilter.html[stop 停用词过滤器]​ 中找到。

停用词可以通过指定一个特殊列表 _none_ 来禁用。例如,使用 _english_ 分析器而不使用停用词,可以通过以下方式做到:

  1. PUT /my_index
  2. {
  3. "settings": {
  4. "analysis": {
  5. "analyzer": {
  6. "my_english": {
  7. "type": "english", (1)
  8. "stopwords": "_none_" (2)
  9. }
  10. }
  11. }
  12. }
  13. }

<1> my_english 分析器是基于 english 分析器。

<2> 但禁用了停用词。

最后,停用词还可以使用一行一个单词的格式保存在文件中。此文件必须在集群的所有节点上,并且通过 stopwords_path 参数设置路径:

  1. PUT /my_index
  2. {
  3. "settings": {
  4. "analysis": {
  5. "analyzer": {
  6. "my_english": {
  7. "type": "english",
  8. "stopwords_path": "stopwords/english.txt" (1)
  9. }
  10. }
  11. }
  12. }
  13. }

<1> 停用词文件的路径,该路径相对于 Elasticsearch 的 config 目录。

使用停用词过滤器(Using the stop Token Filter)

当你创建 custom 分析器时候,可以组合多个 ​{ref}/analysis-stop-tokenfilter.html[stop 停用词过滤器]​ 分词器。例如:我们想要创建一个西班牙语的分析器:

  • 自定义停用词列表
  • light_spanish 词干提取器
  • asciifolding 词汇单元过滤器中除去附加符号

我们可以通过以下设置完成:

  1. PUT /my_index
  2. {
  3. "settings": {
  4. "analysis": {
  5. "filter": {
  6. "spanish_stop": {
  7. "type": "stop",
  8. "stopwords": [ "si", "esta", "el", "la" ] (1)
  9. },
  10. "light_spanish": { (2)
  11. "type": "stemmer",
  12. "language": "light_spanish"
  13. }
  14. },
  15. "analyzer": {
  16. "my_spanish": {
  17. "tokenizer": "spanish",
  18. "filter": [ (3)
  19. "lowercase",
  20. "asciifolding",
  21. "spanish_stop",
  22. "light_spanish"
  23. ]
  24. }
  25. }
  26. }
  27. }
  28. }

<1> 停用词过滤器采用与 standard 分析器相同的参数 stopwordsstopwords_path

<2> 参见 算法提取器(Algorithmic Stemmers)。

<3> 过滤器的顺序非常重要,下面会进行解释。

我们将 spanish_stop 过滤器放置在 asciifolding 过滤器之后.这意味着以下三个词组 estaésta++está++ ,先通过 asciifolding 过滤器过滤掉特殊字符变成了 esta ,随后使用停用词过滤器会将 esta 去除。如果我们只想移除 estaésta ,但是 ++está++ 不想移除。必须将 spanish_stop 过滤器放置在 asciifolding 之前,并且需要在停用词中指定 estaésta

更新停用词(Updating Stopwords)

想要更新分析器的停用词列表有多种方式,分析器在创建索引时,当集群节点重启时候,或者关闭的索引重新打开的时候。

如果你使用 stopwords 参数以内联方式指定停用词,那么你只能通过关闭索引,更新分析器的配置​{ref}/indices-update-settings.html#update-settings-analysis[update index settings API]​,然后在重新打开索引才能更新停用词。

如果你使用 stopwords_path 参数指定停用词的文件路径 ,那么更新停用词就简单了。你只需更新文件(在每一个集群节点上),然后通过两者之中的任何一个操作来强制重新创建分析器:

  • 关闭和重新打开索引 (参考 {ref}/indices-open-close.html[索引的开与关]),
  • 一一重启集群下的每个节点。

当然,更新的停用词不会改变任何已经存在的索引。这些停用词的只适用于新的搜索或更新文档。如果要改变现有的文档,则需要重新索引数据。参加 reindex