我有这样的查询(我已经删除了排序部分,因为它并不重要):
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
我不会得到任何结果。
是否有任何设置来设置查询中的最小字符数,或者我可能需要重写我的查询以实现我想要的?我想在多个字段上运行匹配(在上面的标题和内容字段查询中),这将允许部分匹配与模糊。
答案 0 :(得分:1)
您会收到此行为,因为您设置了"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
搜索期间获得的令牌。使用min_gram
和max_gram
,您可以配置克的最小/最大字符长度。
如果您需要使用omething
等处理案例(开头缺少字母),请尝试使用NGram analyzer。