我正在使用ElasticSearch 7.6,我试图找出一种方法来根据搜索查询的最佳匹配对结果进行排序。
这有两个部分,我将尝试解释,但首先我将提供一个数据Map的演示结构:
"handles" : {
"properties" : {
"references" : {
},
"value" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword"
}
}
}
}
},
所以我们有handles
,我们还有4个属性与handles
具有相同的Map,它们是:summary
、contact_details
、motives
、interests
。
系统必须在handles.value.keyword
等上搜索其余属性。
现在有两种类型的最佳匹配机制:
产品目录
目录是当你访问页面时,你还没有搜索任何东西,系统将在没有搜索查询的情况下获取最佳匹配结果,这是策略:
5个可用属性中的任何属性在数组中至少包含1个元素,都会将分数增加1:
这个例子仅适用于handle
,以防止这篇文章太长:
"query": {
"function_score": {
"query": {
"bool": {
"must": [
]
}
},
"functions": [
{
"script_score": {
"script": {
"source": """
double score = 0;
if (doc['handles.value.keyword'].size() > 0) {
score += 1;
}
return score;
"""
}
}
}
],
"boost_mode": "max"
}
},
这工作完美。
但我的问题是第二种机制。
查询最佳匹配
现在,当你插入一个查询时,当每个属性在数组中至少有一个元素时,我仍然会增加分数,但我也想在每次突出显示5个属性中的任何一个元素时(完全匹配或完全匹配)增加分数。
例如,如果我找到3个匹配项:
1.handles.value:['ben', 'ben10', 'car']
,兴趣.值:['ben']
1.handles.value:['car', 'ben', 'ten']
1.handles.value:['car', 'ben']
,兴趣.value:['ben']
我的搜索查询是ben*
,最佳匹配排序将是:1, 3, 2
由于1包含3个高光,它将是第一个,第3个包含2个高光,它将被排序为第二个,第2个将是第3个,因为它包含一个高光。
“那又怎么样?”**弹性排序函数没有返回的突出显示的上下文,所以我不知道什么值是完全匹配的,所以我不能真正计数。也许我可以遍历脚本中的所有元素,并检查元素中是否包含查询字符串,但这可能非常不稳定,因为我有超过200万个项目,甚至可能更多。
举例说明:
for(handle in doc['handles.value.keyword'])
{
if(handle.value.toString().contains('ben'))
{
score += 2;
}
}
在elasticsearch中有没有合适的方法来实现这样的评分机制?
1条答案
按热度按时间kuarbcqp1#
第一部分(目录)不需要任何脚本。它可以通过在布尔查询中使用简单的exist查询来完成。第二部分比较棘手。大多数处理搜索结果的查询不计算匹配项的数量。但是,如果你总是在搜索中使用前缀,像
match_phrase_prefix
这样的自定义相似度可能会起作用。如果您能够阐明您期望用户键入的内容,我可能能够调整此示例以更好地匹配您的用例。