控制词干提取

开箱即用的词干提取方案永远也不可能完美。 尤其是算法提取器,他们可以愉快的将规则应用于任何他们遇到的词,包含那些你希望保持独立的词。 也许,在你的场景,保持独立的 skiesskiing 是重要的,你不希望把他们提取为 ski (正如 english 分析器那样)。

语汇单元过滤器 keyword_markerstemmer_override 能让我们自定义词干提取过程。

阻止词干提取

语言分析器(查看 配置语言分析器)的参数 stem_exclusion 允许我们指定一个词语列表,让他们不被词干提取。

在内部,这些语言分析器使用 keyword_marker 语汇单元过滤器 来标记这些词语列表为 keywords ,用来阻止后续的词干提取过滤器来触碰这些词语。

例如,我们创建一个简单自定义分析器,使用 porter_stem 语汇单元过滤器,同时阻止 skies 的词干提取:

PUT /my_index
{
  "settings": {
    "analysis": {
      "filter": {
        "no_stem": {
          "type": "keyword_marker",
          "keywords": [ "skies" ] 
        }
      },
      "analyzer": {
        "my_english": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "no_stem",
            "porter_stem"
          ]
        }
      }
    }
  }
}

参数 keywords 可以允许接收多个词语。

使用 analyze API 来测试,可以看到词 skies 没有被提取:

GET /my_index/_analyze?analyzer=my_english
sky skies skiing skis 

返回: sky, skies, ski, ski

Tip

虽然语言分析器只允许我们通过参数 stem_exclusion 指定一个词语列表来排除词干提取, 不过 keyword_marker 语汇单元过滤器同样还接收一个 keywords_path 参数允许我们将所有的关键字存在一个文件。 这个文件应该是每行一个字,并且存在于集群的每个节点。查看 更新停用词(Updating Stopwords) 了解更新这些文件的提示。

自定义提取

在上面的例子中,我们阻止了 skies 被词干提取,但是也许我们希望他能被提干为 sky The stemmer_override 语汇单元过滤器允许我们指定自定义的提取规则。 与此同时,我们可以处理一些不规则的形式,如:mice 提取为 mousefeetfoot

PUT /my_index
{
  "settings": {
    "analysis": {
      "filter": {
        "custom_stem": {
          "type": "stemmer_override",
          "rules": [ 
            "skies=>sky",
            "mice=>mouse",
            "feet=>foot"
          ]
        }
      },
      "analyzer": {
        "my_english": {
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "custom_stem", 
            "porter_stem"
          ]
        }
      }
    }
  }
}

GET /my_index/_analyze?analyzer=my_english
The mice came down from the skies and ran over my feet 

规则来自 original=>stem

stemmer_override 过滤器必须放置在词干提取器之前。

返回 the, mouse, came, down, from, the, sky, and, ran, over, my, foot

Tip

正如 keyword_marker 语汇单元过滤器,规则可以被存放在一个文件中,通过参数 rules_path 来指定位置。