问题描述
要控制基于字段值的文档分数,我在DSL查询中使用了带有function_score的过滤器,这将按我的期望对结果进行排序。
但是,在nesT中实施此方法时,结果却有所不同;分数不应用于过滤器值。通过进一步的调查,我发现scoreFunctionsDescriptor不支持某些版本的C#nesT筛选器。还是这样吗? 您能协助一个可行的方案与nesT一起实施吗? (我是Elastic Search和C#的新手,所以如果是菜鸟问题,请原谅。)
我目前正在使用Elasticsearch v7.6和nesT v7.5.1。
谢谢!
DSL查询
GET /help/_search
{
"query":{
"function_score": {
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "AGC","fields": [
"title^2","description^1"
],"type":"most_fields","fuzziness": "AUTO:4,8","prefix_length": 2,"boost": 5
}
}
]
}
},** "functions": [
{
"filter": {
"term":{
"product":"A"
}
},"weight": 45
},{
"filter": {
"term":{
"product":"B"
}
},"weight": 20
},{
"filter": {
"term":{
"product":"C"
}
},"weight": 10
}
],**
"score_mode": "max","boost_mode": "multiply"
}
}
}```
解决方法
根据进一步的调查,我发现ScoreFunctionsDescriptor不支持某些版本的C#NEST筛选器。还是这样吗?
The function you're looking for is a weight function(已应用过滤器)。客户端在很长一段时间内都支持此功能。
等效于客户端
var response = client.Search<object>(s => s
.Query(q => q
.FunctionScore(fs => fs
.Query(fsq => fsq
.Bool(b => b
.Must(mu => mu
.MultiMatch(mm => mm
.Query("AGC")
.Fields(new[] { "title^2","description^1" })
.Type(TextQueryType.MostFields)
.Fuzziness(Fuzziness.AutoLength(4,8))
.PrefixLength(2)
.Boost(5)
)
)
)
)
.Functions(fu => fu
.Weight(w => w
.Filter(f => f
.Term("product","A")
)
.Weight(45)
)
.Weight(w => w
.Filter(f => f
.Term("product","B")
)
.Weight(20)
)
.Weight(w => w
.Filter(f => f
.Term("product","C")
)
.Weight(10)
)
)
.ScoreMode(FunctionScoreMode.Max)
.BoostMode(FunctionBoostMode.Multiply)
)
)
);
您可能需要看几件事:
-
description^1
可以简单地用description
代替,因为默认提升为1 - 这可能更好地表示为对每个权重函数中的每个查询都带有
bool
子句的should
查询,并且施加的提升类似于权重的使用方式。像
var response = client.Search<object>(s => s
.Query(q => q
.Bool(b => b
.Must(mu => mu
.MultiMatch(mm => mm
.Query("AGC")
.Fields(new[] { "title^2","description^1" })
.Type(TextQueryType.MostFields)
.Fuzziness(Fuzziness.AutoLength(4,8))
.PrefixLength(2)
.Boost(5)
)
)
.Should(
sh => sh.Term(t => t
.Field("product")
.Value("A")
.Boost(45)
),sh => sh.Term(t => t
.Field("product")
.Value("B")
.Boost(20)
),sh => sh.Term(t => t
.Field("product")
.Value("C")
.Boost(10)
)
)
)
)
);