我们有一个非常基本的查询,我们正在使用该查询来允许用户提供查询文本,然后它可以促进不同字段上的匹配。现在我们要添加另一个boost based on votes,但是不确定在哪里嵌套FunctionScore
。
我们最初的查询是:
var results = await _ElasticClient.SearchAsync<dynamic>(s => s
.Query(q => q
.MultiMatch(mm => mm
.Fields(f => f
.Field("name^5")
.Field("hobbies^2")
)
.Query(queryText)
)
)
);
如果我尝试将
FunctionScore
嵌套在MultiMatch
周围,则它基本上会忽略查询/字段,而只返回索引中的所有内容:var results = await _ElasticClient.SearchAsync<dynamic>(s => s
.Query(q => q
.FunctionScore(fs => fs
.Query(q2 => q2
.MultiMatch(mm => mm
.Fields(f => f
.Field("name^5")
.Field("hobbies^2")
)
.Query(queryText)
)
)
)
)
);
我的期望是,由于我没有提供
FunctionScore
或任何Functions
,因此基本上应该执行与上述完全相同的操作。然后,仅添加FunctionScore
即可根据我提供的功能提高结果(在我的情况下,仅基于votes
字段即可增强FieldValueFactor
)。与此相关的文档有些模糊,尤其是对于某些组合,例如
MultiMatch
,FunctionScore
和查询文本。我的确找到了this answer,但包括查询文本时并未涵盖。我敢肯定,这归结于我对 flex 查询的工作原理仍不甚了解,但我只是没有找到很多解决方案(我认为这很普遍):
最佳答案
您的function_score
查询是正确的,但未看到预期结果的原因是由于NEST中的一项功能称为conditionless queries。对于function_score
查询,当没有函数时,它将被视为无条件的,从请求中发送的序列化表格中省略查询。
最简单的方法是举一个小例子
private static void Main()
{
var defaultIndex = "my-index";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool, new InMemoryConnection())
.DefaultIndex(defaultIndex)
.DisableDirectStreaming()
.PrettyJson()
.OnRequestCompleted(callDetails =>
{
if (callDetails.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{callDetails.HttpMethod} {callDetails.Uri} \n" +
$"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
}
Console.WriteLine();
if (callDetails.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
});
var client = new ElasticClient(settings);
var queryText = "query text";
var results = client.Search<dynamic>(s => s
.Query(q => q
.FunctionScore(fs => fs
.Query(q2 => q2
.MultiMatch(mm => mm
.Fields(f => f
.Field("name^5")
.Field("hobbies^2")
)
.Query(queryText)
)
)
)
)
);
}
发出以下请求
POST http://localhost:9200/my-index/object/_search?pretty=true&typed_keys=true
{}
您可以通过将查询标记为
Verbatim
来禁用无条件功能var results = client.Search<dynamic>(s => s
.Query(q => q
.FunctionScore(fs => fs
.Verbatim() // <-- send the query *exactly as is*
.Query(q2 => q2
.MultiMatch(mm => mm
.Fields(f => f
.Field("name^5")
.Field("hobbies^2")
)
.Query(queryText)
)
)
)
)
);
现在,这将发送查询
POST http://localhost:9200/my-index/object/_search?pretty=true&typed_keys=true
{
"query": {
"function_score": {
"query": {
"multi_match": {
"query": "query text",
"fields": [
"name^5",
"hobbies^2"
]
}
}
}
}
}
关于elasticsearch - 将FunctionScore/FieldValueFactor添加到MultiMatch查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52998929/