我目前正在尝试在NEST中实现“function_score”查询,其中的函数仅在过滤器匹配时应用。
看起来不像FunctionScoreFunctionsDescriptor支持添加过滤器。这个功能是否会很快添加?
这是我希望能够实现的一个超级基本示例:
"function_score": {
"query": {...}, // base ES query
"functions": [
{
"filter": {...},
"script_score": {"script": "25"}
},
{
"filter": {...},
"script_score": {"script": "15"}
}
],
"score_mode": "first", // take the first script_score where the filter matches
"boost_mode": "sum" // and add this to the base ES query score
}
我目前正在使用Elasticsearch v1.1.0和NEST v1.0.0-beta1预发布。
谢谢!
答案 0 :(得分:5)
它已经实施:
_client.Search<ElasticsearchProject>(s =>
s.Query(q=>q
.FunctionScore(fs=>fs.Functions(
f=>f
.ScriptScore(ss=>ss.Script("25"))
.Filter(ff=>ff.Term(t=>t.Country, "A")),
f=> f
.ScriptScore(ss=>ss.Script("15"))
.Filter(ff=>ff.Term("a","b")))
.ScoreMode(FunctionScoreMode.first)
.BoostMode(FunctionBoostMode.sum))));
答案 1 :(得分:3)
Udi的答案对我不起作用。似乎在新版本(v 2.3,C#)中ScoreFunctionsDescriptor
类没有Filter()方法。
但我找到了解决方案。您可以提供IScoreFunction
的数组。为此,您可以使用new FunctionScoreFunction()
或使用我的助手类:
class CustomFunctionScore<T> : FunctionScoreFunction
where T: class
{
public CustomFunctionScore(Func<QueryContainerDescriptor<T>, QueryContainer> selector, double? weight = null)
{
this.Filter = selector.Invoke(new QueryContainerDescriptor<T>());
this.Weight = weight;
}
}
使用这个类,可以通过这种方式应用过滤器(这只是一个例子):
SearchDescriptor<BlobPost> searchDescriptor = new SearchDescriptor<BlobPost>()
.Query(qr => qr
.FunctionScore(fs => fs
.Query(q => q.Bool(b => b.Should(s => s.Match(a => a.Field(f => f.FirstName).Query("john")))))
.ScoreMode(FunctionScoreMode.Max)
.BoostMode(FunctionBoostMode.Sum)
.Functions(
new[]
{
new CustomFunctionScore<BlobPost>(q => q.Match(a => a.Field(f => f.Id).Query("my_id")), 10),
new CustomFunctionScore<BlobPost>(q => q.Match(a => a.Field(f => f.FirstName).Query("john")), 10),
}
)
)
);