为什么我的 Elasticsearch 多匹配查询只查找前缀?
Why does my Elasticsearch multi-match query look only for prefixes?
我正在尝试编写一个 Elasticsearch 多匹配查询(使用 Java API)来创建一个 "search-as-you-type" 程序。查询应用于两个字段,title
和 description
,它们被分析为 ngrams。
我的问题是,Elasticsearch 似乎只尝试查找像我的查询一样的单词 beginning。例如,如果我搜索 "nut",那么它会匹配包含“nut”、“nuts”、“Nutella”等,但它不匹配带有“walnut”的文档,应该匹配。
这是我的设置:
{
"index": {
"analysis": {
"analyzer": {
"edgeNGramAnalyzer": {
"tokenizer": "edgeTokenizer",
"filter": [
"word_delimiter",
"lowercase",
"unique"
]
}
},
"tokenizer": {
"edgeTokenizer": {
"type": "edgeNGram",
"min_gram": "3",
"max_gram": "8",
"token_chars": [
"letter",
"digit"
]
}
}
}
}
}
这是我映射的相关部分:
{
"content": {
"properties": {
"title": {
"type": "text",
"analyzer": "edgeNGramAnalyzer",
"fields": {
"sort": {
"type": "keyword"
}
}
},
"description": {
"type": "text",
"analyzer": "edgeNGramAnalyzer",
"fields": {
"sort": {
"type": "keyword"
}
}
}
}
}
}
这是我的查询:
new MultiMatchQueryBuilder(query).field("title", 3).field("description", 1).fuzziness(0).tieBreaker(1).minimumShouldMatch("100%")
你知道我做错了什么吗?
那是因为您使用的是 edgeNGram
tokenizer instead of nGram
。前者仅索引前缀,而后者将索引前缀、后缀以及数据的子部分。
将您的分析器定义更改为此,它应该会按预期工作:
{
"index": {
"analysis": {
"analyzer": {
"edgeNGramAnalyzer": {
"tokenizer": "edgeTokenizer",
"filter": [
"word_delimiter",
"lowercase",
"unique"
]
}
},
"tokenizer": {
"edgeTokenizer": {
"type": "nGram", <---- change this
"min_gram": "3",
"max_gram": "8",
"token_chars": [
"letter",
"digit"
]
}
}
}
}
}
我正在尝试编写一个 Elasticsearch 多匹配查询(使用 Java API)来创建一个 "search-as-you-type" 程序。查询应用于两个字段,title
和 description
,它们被分析为 ngrams。
我的问题是,Elasticsearch 似乎只尝试查找像我的查询一样的单词 beginning。例如,如果我搜索 "nut",那么它会匹配包含“nut”、“nuts”、“Nutella”等,但它不匹配带有“walnut”的文档,应该匹配。
这是我的设置:
{
"index": {
"analysis": {
"analyzer": {
"edgeNGramAnalyzer": {
"tokenizer": "edgeTokenizer",
"filter": [
"word_delimiter",
"lowercase",
"unique"
]
}
},
"tokenizer": {
"edgeTokenizer": {
"type": "edgeNGram",
"min_gram": "3",
"max_gram": "8",
"token_chars": [
"letter",
"digit"
]
}
}
}
}
}
这是我映射的相关部分:
{
"content": {
"properties": {
"title": {
"type": "text",
"analyzer": "edgeNGramAnalyzer",
"fields": {
"sort": {
"type": "keyword"
}
}
},
"description": {
"type": "text",
"analyzer": "edgeNGramAnalyzer",
"fields": {
"sort": {
"type": "keyword"
}
}
}
}
}
}
这是我的查询:
new MultiMatchQueryBuilder(query).field("title", 3).field("description", 1).fuzziness(0).tieBreaker(1).minimumShouldMatch("100%")
你知道我做错了什么吗?
那是因为您使用的是 edgeNGram
tokenizer instead of nGram
。前者仅索引前缀,而后者将索引前缀、后缀以及数据的子部分。
将您的分析器定义更改为此,它应该会按预期工作:
{
"index": {
"analysis": {
"analyzer": {
"edgeNGramAnalyzer": {
"tokenizer": "edgeTokenizer",
"filter": [
"word_delimiter",
"lowercase",
"unique"
]
}
},
"tokenizer": {
"edgeTokenizer": {
"type": "nGram", <---- change this
"min_gram": "3",
"max_gram": "8",
"token_chars": [
"letter",
"digit"
]
}
}
}
}
}