我们有一个非常基本的查询,我们正在使用该查询来允许用户提供查询文本,然后它可以促进不同字段上的匹配。现在我们要添加另一个boost based on votes,但不确定将value
嵌套在何处。
我们的原始查询是:
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
的{{1}}字段可以增强结果)。
与此相关的文档有些模糊,尤其是对于某些组合,例如votes
,FieldValueFactor
和查询文本。我确实找到了this answer,但是在包含查询文本时却没有涵盖。
我敢肯定,这归因于我对弹性查询的工作方式仍不甚了解,但我只是没有找到很多东西来涵盖以下情况(我认为这是很常见的):
答案 0 :(得分:1)
您的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"
]
}
}
}
}
}