elasticsearch - 将FunctionScore/FieldValueFactor添加到MultiMatch查询

标签 elasticsearch nest

我们有一个非常基本的查询,我们正在使用该查询来允许用户提供查询文本,然后它可以促进不同字段上的匹配。现在我们要添加另一个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)。

与此相关的文档有些模糊,尤其是对于某些组合,例如MultiMatchFunctionScore和查询文本。我的确找到了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/

    相关文章:

    elasticsearch - 如何使用 NEST 客户端获取 Elasticsearch 服务器的版本?

    elasticsearch - 从 Nest 客户端 Elasticsearch 2.3 序列化查询

    Elasticsearch NEST 客户端创建多字段并完成

    node.js - “NestMicroservice”错误地实现了接口(interface) 'INestMicroservice'

    c# - 如何将 MSSQL 同步到 Elasticsearch?

    nest - 用于单元测试 Elasticsearch 项目的 InMemoryConnection

    elasticsearch - 如何在 logstash conf 文件中使用包含?

    elasticsearch - 如何使用 Elasticsearch 突出显示单词中的 ngram 标记

    elasticsearch - Elasticsearch 文件系统上索引的大小

    elasticsearch - Elasticsearch对子孙的内在打击