我有这样的查询(我删除了排序部分,因为没有关系):
GET _search
{
"query": {
"multi_match": {
"query": "somethi",
"fields": [ "title", "content"],
"fuzziness" : "AUTO",
"prefix_length" : 0
}
}
}
运行此命令时,将得到如下结果:
"hits": [
{
"_index": "test_index",
"_type": "article",
"_id": "2",
"_score": 0.083934024,
"_source": {
"title": "Matching something abc",
"content": "This is a piece of content",
"categories": [
{
"name": "B",
"weight": 4
}
]
},
"sort": [
4,
0.083934024,
"article#2"
]
},
{
"_index": "test_index",
"_type": "article",
"_id": "3",
"_score": 0.18436861,
"_source": {
"title": "Matching something abc",
"content": "This is a piece of content containing something",
"categories": [
{
"name": "C",
"weight": 3
}
]
},
"sort": [
3,
0.18436861,
"article#3"
]
},
...
因此,毫无疑问可以得到预期的结果。但是我注意到,我从查询中删除一个字母改成
someth
,Elasticsearch不会返回任何结果。这对我来说很奇怪。看来
multi_match
正在做部分匹配,但是以某种方式要求使用最少的x个字符。如果尝试输入omethin
这样的查询,我将获得结果,但是仅使用omethi
不会得到任何结果。是否有任何设置可以设置查询中的最小字符数,或者可能需要重写查询才能实现所需的功能?我想在多个字段上运行匹配(在上面的标题和内容字段查询中),这将允许部分匹配以及模糊性。
最佳答案
之所以会出现这种现象,是因为您设置了"fuzziness": "AUTO"
参数,这意味着在一个字符数超过5个的单词中,最多可以将两个字符放错位置。通常,fuzziness parameter告诉elasticsearch查找最多两个变化的所有术语,其中变化是单个字符的插入,删除或替换。对于模糊性,不可能有两个以上的更改。
如果需要使用部分匹配进行搜索,则可以尝试使用Edge NGram analyzer配置索引并将其设置为title
和content
字段。您可以轻松测试其工作方式:
使用以下映射创建na索引:
PUT http://127.0.0.1:9200/test
{
"settings": {
"analysis": {
"analyzer": {
"edge_ngram_analyzer": {
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "edge_ngram",
"min_gram": 2,
"max_gram": 10,
"token_chars": [
"letter",
"digit"
]
}
}
}
}
}
并运行以下查询:
curl -X POST \
'http://127.0.0.1:9200/test/_analyze?pretty=true' \
-d '{
"analyzer" : "edge_ngram_analyzer",
"text" : ["something"]
}'
结果,您将获得:
{
"tokens": [
{
"token": "so",
...
},
{
"token": "som",
...
},
{
"token": "some",
...
},
{
"token": "somet",
...
},
{
"token": "someth",
...
},
{
"token": "somethi",
...
},
{
"token": "somethin",
...
},
{
"token": "something",
...
}
]
}
这些是您在使用
edge_ngram_analyzer
搜索期间将获得的 token 。使用min_gram
和max_gram
,您可以配置gram中字符的最小/最大长度。如果您需要使用
omething
等处理情况(开头缺少字母),请尝试使用NGram analyzer进行处理。
关于elasticsearch - Elasticsearch-multi_match和简短查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45539976/