控制词干提取
开箱即用的词干提取方案永远也不可能完美。尤其是算法提取器,他们可以愉快的将规则应用于任何他们遇到的词,包含那些你希望保持独立的词。也许,在你的场景,保持独立的 skies
和 skiing
是重要的,你不希望把他们提取为 ski
(正如 english
分析器那样)。
语汇单元过滤器 {ref}/analysis-keyword-marker-tokenfilter.html[keyword_marker
] 和
{ref}/analysis-stemmer-override-tokenfilter.html[stemmer_override
]能让我们自定义词干提取过程。
阻止词干提取
语言分析器(查看 configuring-language-analyzers)的参数 stem_exclusion
允许我们指定一个词语列表,让他们不被词干提取。
在内部,这些语言分析器使用
{ref}/analysis-keyword-marker-tokenfilter.html[keyword_marker
语汇单元过滤器]来标记这些词语列表为 keywords ,用来阻止后续的词干提取过滤器来触碰这些词语。例如,我们创建一个简单自定义分析器,使用
{ref}/analysis-porterstem-tokenfilter.html[porter_stem
] 语汇单元过滤器,同时阻止 skies
的词干提取:
PUT /my_index
{
"settings": {
"analysis": {
"filter": {
"no_stem": {
"type": "keyword_marker",
"keywords": [ "skies" ] (1)
}
},
"analyzer": {
"my_english": {
"tokenizer": "standard",
"filter": [
"lowercase",
"no_stem",
"porter_stem"
]
}
}
}
}
}
<1> 参数 keywords
可以允许接收多个词语。
使用 analyze
API 来测试,可以看到词 skies
没有被提取:
GET /my_index/_analyze?analyzer=my_english
sky skies skiing skis (1)
<1> 返回: sky
, skies
, ski
, ski
[TIP]
虽然语言分析器只允许我们通过参数 stem_exclusion
指定一个词语列表来排除词干提取,不过 keyword_marker
语汇单元过滤器同样还接收一个 keywords_path
参数允许我们将所有的关键字存在一个文件。这个文件应该是每行一个字,并且存在于集群的每个节点。查看 updating-stopwords 了解更新这些文件的提示。
自定义提取
在上面的例子中,我们阻止了 skies
被词干提取,但是也许我们希望他能被提干为 sky
。The
{ref}/analysis-stemmer-override-tokenfilter.html[stemmer_override
] 语汇单元过滤器允许我们指定自定义的提取规则。与此同时,我们可以处理一些不规则的形式,如:mice
提取为 mouse
和 feet
到 foot
:
PUT /my_index
{
"settings": {
"analysis": {
"filter": {
"custom_stem": {
"type": "stemmer_override",
"rules": [ (1)
"skies=>sky",
"mice=>mouse",
"feet=>foot"
]
}
},
"analyzer": {
"my_english": {
"tokenizer": "standard",
"filter": [
"lowercase",
"custom_stem", (2)
"porter_stem"
]
}
}
}
}
}
GET /my_index/_analyze?analyzer=my_english
The mice came down from the skies and ran over my feet (3)
<1> 规则来自 original=>stem
。
<2> stemmer_override
过滤器必须放置在词干提取器之前。
<3> 返回 the
, mouse
, came
, down
, from
, the
, sky
,and
, ran
, over
, my
, foot
。
TIP: 正如 keyword_marker
语汇单元过滤器,规则可以被存放在一个文件中,通过参数 rules_path
来指定位置。