elasticsearch 短语前缀停止查找
elasticsearch phrase prefix stops finding
我正在使用 elasticsearch 短语前缀查询进行一些自动完成。
它通常工作得很好,但有时不再找到不完整的单词,尽管多一个或少一个字母它确实找到了它。
例如:它在查询 "Anomal" 和查询 "Anomalie" 中确实找到了包含 "Anomalie" 的内容,但在 "Anomali" 中找不到任何内容。这对于用户体验来说真的很奇怪!
我之前的谷歌搜索让我尝试禁用停用词,但这并没有解决我的问题。我尝试在分析器中使用停用词配置作为过滤器。
重现:
索引创建、配置和添加文档:
curl -XPUT 'http://localhost:9200/elastictests/' -d '{
"settings" : {
"index" : {
"analysis" : {
"filter" : {
"french_stemmer" : {
"type" : "stemmer",
"name" : "light_french"
},
"no_stop" : {
"type" : "stop",
"stopwords" : "_none_"
}
},
"analyzer" : {
"default" : {
"type" : "custom",
"stopwords" : "_none_",
"filter" : [ "standard", "lowercase", "asciifolding", "word_delimiter", "french_stemmer", "no_stop" ],
"tokenizer" : "standard"
}
}
}
}
}
}'
curl -XPUT 'http://localhost:9200/elastictests/test/1' -d '{
"title": "Anomalie"
}'
这些查询找到了文档:
curl -XGET 'http://localhost:9200/elastictests/_search?pretty=1' -d '
{
"query" : {
"match" : {
"title" : "Anomalie"
}
}
}
}
'
curl -XGET 'http://localhost:9200/elastictests/_search?pretty=1' -d '
{
"query" : {
"match" : {
"title" : {
"query": "Anomalie",
"type": "phrase_prefix"
}
}
}
}
'
curl -XGET 'http://localhost:9200/elastictests/_search?pretty=1' -d '
{
"query" : {
"match" : {
"title" : {
"query": "Anomal",
"type": "phrase_prefix"
}
}
}
}
'
但是这个没有找到文档也没有错误:
curl -XGET 'http://localhost:9200/elastictests/_search?pretty=1' -d '
{
"query" : {
"match" : {
"title" : {
"query": "Anomali",
"type": "phrase_prefix"
}
}
}
}
'
知道为什么吗?
这是因为 french_stemmer 源于 Anomalie => anomal.
但是 anomali 不会被词干化为 anomal.
Anomalie 的索引词 => anomal
类似地,当查询词是 Anomalie 时,搜索词被分析为 anomal 并且匹配标题。
然而,当查询是 "Anomali" 时,它被分析为 "anomali",即没有发生词干提取。由于索引项是 "anomal",因此没有匹配前缀或其他。
如果您从 OP 中描述的自定义分析器中删除词干分析器,您应该会得到针对此特定 use-case
的预期结果
示例:
get elastictests/_analyze?field=title&text=Anomalie
{
"tokens": [
{
"token": "**anomal**",
"start_offset": 0,
"end_offset": 8,
"type": "<ALPHANUM>",
"position": 1
}
]
}
get elastictests/_analyze?field=title&text=Anomali
{
"tokens": [
{
"token": "**anomali**",
"start_offset": 0,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 1
}
]
我正在使用 elasticsearch 短语前缀查询进行一些自动完成。 它通常工作得很好,但有时不再找到不完整的单词,尽管多一个或少一个字母它确实找到了它。
例如:它在查询 "Anomal" 和查询 "Anomalie" 中确实找到了包含 "Anomalie" 的内容,但在 "Anomali" 中找不到任何内容。这对于用户体验来说真的很奇怪!
我之前的谷歌搜索让我尝试禁用停用词,但这并没有解决我的问题。我尝试在分析器中使用停用词配置作为过滤器。
重现:
索引创建、配置和添加文档:
curl -XPUT 'http://localhost:9200/elastictests/' -d '{
"settings" : {
"index" : {
"analysis" : {
"filter" : {
"french_stemmer" : {
"type" : "stemmer",
"name" : "light_french"
},
"no_stop" : {
"type" : "stop",
"stopwords" : "_none_"
}
},
"analyzer" : {
"default" : {
"type" : "custom",
"stopwords" : "_none_",
"filter" : [ "standard", "lowercase", "asciifolding", "word_delimiter", "french_stemmer", "no_stop" ],
"tokenizer" : "standard"
}
}
}
}
}
}'
curl -XPUT 'http://localhost:9200/elastictests/test/1' -d '{
"title": "Anomalie"
}'
这些查询找到了文档:
curl -XGET 'http://localhost:9200/elastictests/_search?pretty=1' -d '
{
"query" : {
"match" : {
"title" : "Anomalie"
}
}
}
}
'
curl -XGET 'http://localhost:9200/elastictests/_search?pretty=1' -d '
{
"query" : {
"match" : {
"title" : {
"query": "Anomalie",
"type": "phrase_prefix"
}
}
}
}
'
curl -XGET 'http://localhost:9200/elastictests/_search?pretty=1' -d '
{
"query" : {
"match" : {
"title" : {
"query": "Anomal",
"type": "phrase_prefix"
}
}
}
}
'
但是这个没有找到文档也没有错误:
curl -XGET 'http://localhost:9200/elastictests/_search?pretty=1' -d '
{
"query" : {
"match" : {
"title" : {
"query": "Anomali",
"type": "phrase_prefix"
}
}
}
}
'
知道为什么吗?
这是因为 french_stemmer 源于 Anomalie => anomal.
但是 anomali 不会被词干化为 anomal.
Anomalie 的索引词 => anomal
类似地,当查询词是 Anomalie 时,搜索词被分析为 anomal 并且匹配标题。
然而,当查询是 "Anomali" 时,它被分析为 "anomali",即没有发生词干提取。由于索引项是 "anomal",因此没有匹配前缀或其他。
如果您从 OP 中描述的自定义分析器中删除词干分析器,您应该会得到针对此特定 use-case
的预期结果示例:
get elastictests/_analyze?field=title&text=Anomalie
{
"tokens": [
{
"token": "**anomal**",
"start_offset": 0,
"end_offset": 8,
"type": "<ALPHANUM>",
"position": 1
}
]
}
get elastictests/_analyze?field=title&text=Anomali
{
"tokens": [
{
"token": "**anomali**",
"start_offset": 0,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 1
}
]