我正在构建一个具有键入时自动完成功能的搜索 UI。为了实现这一点,我在 ElasticSearch 7.10 中创建了一个索引,并在name字段上使用了 edge_ngram 标记器和分析器:
mappings: {
properties: {
id: { type: "text" },
name: {
type: "text",
analyzer: "index_ngram_analyzer",
search_analyzer: "search_term_analyzer",
term_vector: "with_positions_offsets"
}
}
},
settings: {
max_ngram_diff: 27,
analysis: {
tokenizer: {
ngram_tokenizer: {
type: "edge_ngram",
min_gram: 1,
max_gram: 28,
token_chars: ["letter", "digit"]
}
},
analyzer: {
index_ngram_analyzer: {
type: "custom",
tokenizer: "ngram_tokenizer",
filter: ["lowercase", "asciifolding"]
},
search_term_analyzer: {
type: "custom",
tokenizer: "standard",
filter: ["lowercase", "asciifolding"]
}
}
}
在每个结果中,我想突出显示结果中与用户迄今为止输入的内容相匹配的部分。我使查询变得模糊,以确保即使用户犯了错字或拼写错误,我们仍然会显示相关结果。不幸的是,这似乎有一个不幸的副作用,即导致突出显示不应该的额外字母。例如,以下查询:
query: {
match: {
name: {
query: "anx",
fuzziness: 'auto',
},
},
},
highlight: {
fields: {
name: {},
},
},
产生以下结果:
{
"hits": [
{
"_index": "symptoms",
"_type": "_doc",
"_id": "anxiety",
"_score": 1.7119179,
"_source": {
"id": "anxiety",
"name": "Anxiety",
},
"highlight": {
"name": [
"<em>Anxi</em>ety"
]
}
}
]
}
如您所见,Anxi尽管用户只输入anx了内容,但 ElasticSearch 仍在突出显示 -i不应该是突出显示的一部分。我认为这是因为查询的模糊性导致在ngram上anx匹配。anxi我的期望是anxngram 上的匹配会得分更高,因为它是完全匹配的,因此只会Anx在结果中突出显示。为什么这没有发生?我能做些什么来解决这个问题?
编辑:我尝试使用explain: true. 奇怪的是,anxngram 似乎确实比anxingram 得分更高,但anxingram 仍然是突出显示的:
"_explanation": {
"value": 1.7119179,
"description": "sum of:",
"details": [
{
"value": 0.39505798,
"description": "weight(name:an in 0) [PerFieldSimilarity], result of:",
"details": [
...
]
},
{
"value": 0.79011595,
"description": "weight(name:anx in 0) [PerFieldSimilarity], result of:",
"details": [
...
]
},
{
"value": 0.5267439,
"description": "weight(name:anxi in 0) [PerFieldSimilarity], result of:",
"details": [
...
]
}
]
}
(为简洁起见省略了不必要的细节)
为什么 ngram 荧光笔似乎突出显示最长的 ngram 而不是得分最高的 ngram?有没有我可以修改的设置来改变这种行为?
plain和荧光笔都unified以上述方式运行。尝试使用fvh荧光笔会导致突出显示的字母太少而不是太多。在上面的示例中,fvh荧光笔突出显示An. anxiety此外,当使用fvh荧光笔对整个单词运行查询时,它只会突出显示ngram 得分高于匹配的两个较短 ngramAnxie的事实。anxiety