使用停用词(stopwords)edit

移除停用词的工作是由stop词元过滤器(token filter)完成的,可以通过创建自定义的分析器来使用它。但是,也有一些自带的分析器预置了stop过滤器:

语言分析器(language analyzers)
每个语言分析器默认使用与该语言相适的停用词列表,例如:english 英语分析器使用 _english_ 停用词列表。
标准分析器(standard analyzer)
默认使用空的停用词列表:_none_ ,实际上是禁用了停用词。
模式分析器(pattern analyzer)
默认使用空的停用词列表:为 _none_ ,与 standard 分析器类似。

停用词(stopwords)和标准分析器(standard analyzer)edit

为了让standard分析器使用自定义的停用词,我们只需在创建一个分析器时使用已配置好的分析器,然后传入停用词列表:

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": { 
          "type": "standard", 
          "stopwords": [ "and", "the" ] 
        }
      }
    }
  }
}

自定义的分析器名称为 my_analyzer

这个分析器是一个使用了一些自定义配置的标准(standard)分析器

过滤掉的停用词包括 andthe

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

保持词元在原内容中的位置(maintaining positions)edit

analyzer API的输出结果很有趣:

GET /my_index/_analyze?analyzer=my_analyzer
The quick and the dead
{
   "tokens": [
      {
         "token":        "quick",
         "start_offset": 4,
         "end_offset":   9,
         "type":         "<ALPHANUM>",
         "position":     1 
      },
      {
         "token":        "dead",
         "start_offset": 18,
         "end_offset":   22,
         "type":         "<ALPHANUM>",
         "position":     4
      }
   ]
}

position标记了每个词元(token)的位置。

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

指定停用词(specifying stopwordsedit

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

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

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

"stopwords": "_english_"

Elasticsearch 中预定义的与语言相关的停用词列表可以在文档 stop 词元过滤器​ 中找到。

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

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_english": {
          "type":      "english", 
          "stopwords": "_none_" 
        }
      }
    }
  }
}

my_english 分析器是基于 english 分析器。

但禁用了停用词。

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

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_english": {
          "type":           "english",
          "stopwords_path": "stopwords/english.txt" 
        }
      }
    }
  }
}

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

使用 stop词元过滤器(token filteredit

当你需要自定义一个分析器的时候,可以把stop词元过滤器和一个分词器(tokenizer)及其他若干个词元过滤器(token filter)组合起来. 例如:我们想要创建一个西班牙语的分析器:

  • 自定义停用词列表
  • 使用light_spanish词干提取器(stemmer)
  • 使用asciifolding过滤器去掉附加符号(diacritics), 比如变音符号

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

PUT /my_index
{
  "settings": {
    "analysis": {
      "filter": {
        "spanish_stop": {
          "type":        "stop",
          "stopwords": [ "si", "esta", "el", "la" ]  
        },
        "light_spanish": { 
          "type":     "stemmer",
          "language": "light_spanish"
        }
      },
      "analyzer": {
        "my_spanish": {
          "tokenizer": "spanish",
          "filter": [ 
            "lowercase",
            "asciifolding",
            "spanish_stop",
            "light_spanish"
          ]
        }
      }
    }
  }
}

stop词元过滤器(token filter)采用与 standard分析器相同的 stopwordsstopwords_path 参数。

参见 算法提取器(algorithmic stemmers)

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

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

更新停用词(Updating Stopwords)edit

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

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

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

  • 关闭和重新打开索引 (参考 索引的开与关),
  • 一一重启集群下的每个节点。

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