【问题标题】:Get raw query from NEST client从 NEST 客户端获取原始查询
【发布时间】:2015-05-10 10:23:40
【问题描述】:

是否可以从 NEST 客户端获取原始搜索查询?

var result = client.Search<SomeType>(s => s
                .AllIndices()
                .Type("SomeIndex")
                .Query(query => query
                    .Bool(boolQuery => BooleanQuery(searchRequest, mustMatchQueries)))
                );

我真的很想调试为什么我会得到某些结果。

【问题讨论】:

标签: elasticsearch nest


【解决方案1】:

执行此操作的方法似乎随每个主要版本而变化,因此答案的数量令人困惑。 如果您希望它在 NEST 6.x 中工作,并且您希望在实际发送之前查看反序列化的请求,这相当容易:

var json = elasticClient.RequestResponseSerializer.SerializeToString(request);

如果您在 Visual Studio 中进行调试,在该行之后放置一个断点会很方便,当您点击它时,将鼠标悬停在上面的 json 变量上并点击 magnifying glass thingy。您将获得一个很好的 JSON 格式视图。

【讨论】:

  • 你的request 是什么?你是怎么定义的?
  • @LxL 这是您在使用object initialization syntax 时创建的东西。我不使用fluent API,这实际上是原因之一。
  • 对于那些使用 NEST 6.x 并使用 fluent API 的人,this answer 为我工作。
【解决方案2】:

您可以从RequestInformation获取原始查询json:

var rawQuery = Encoding.UTF8.GetString(result.RequestInformation.Request);

或者在您的ConnectionSettings 对象上启用跟踪,这样 NEST 将打印每个请求以跟踪输出

var connectionSettings = new ConnectionSettings(new Uri(elasticsearchUrl));
connectionSettings.EnableTrace(true);
var client = new ElasticClient(connectionSettings); 

巢 7.x

为客户端创建设置时启用调试模式:

var settings = new ConnectionSettings(connectionPool)
    .DefaultIndex("index_name")
    .EnableDebugMode()
var client = new ElasticClient(settings); 

那么您的response.DebugInformation 将包含有关发送到elasticsearch 的请求和来自elasticsearch 的响应的信息。 Docs.

【讨论】:

  • 如果您需要查询之前,它会被发送:Encoding.UTF8.GetString(elasticClient.Serializer.Serialize(query))
  • result 没有 RequestInformation 属性,我需要添加一些依赖才能访问它吗?
  • @RicardoSilva 可能您正在使用 NEST 2.x。并且答案是在考虑版本 1.x 的情况下编写的。检查this一个。
  • RequestInformation 不在 ISearchResponse 中:\
  • 对于更高版本,System.Text.Encoding.UTF8.GetString(result.ApiCall.RequestBodyInBytes) 可能会更幸运,详情请参阅下面的答案
【解决方案3】:

对于 NEST / Elasticsearch.NET v6.0.2,使用 IResponse 对象的 ApiCall 属性。你可以像这样写一个方便的扩展方法:

public static string ToJson(this IResponse response)
{
    return Encoding.UTF8.GetString(response.ApiCall.RequestBodyInBytes);
}

或者,如果您想记录对 Elastic 的所有请求,您可以使用连接对象拦截响应:

var node = new Uri("https://localhost:9200");
var pool = new SingleNodeConnectionPool(node);
var connectionSettings = new ConnectionSettings(pool, new HttpConnection());
connectionSettings.OnRequestCompleted(call =>
{
    Debug.Write(Encoding.UTF8.GetString(call.RequestBodyInBytes));
});

【讨论】:

  • 在我的情况下,RequestBodyInBytes 为空。使用connectionSettings.DisableDirectStreaming(true) 它可以工作——请求/响应序列化不再默认保存在内存中。
  • 这适用于 7.11.0,上面对 DisableDirectStreaming 进行了评论
【解决方案4】:

在 ElasticSearch 5.x 中,ISearchResponse&lt;T&gt; 中不存在 RequestInformation.Request 属性,但 similar to the answer provided here 您可以使用 Elastic Client Serializer 和 SearchDescriptor 生成原始查询 JSON。例如,对于给定的 NEST 搜索查询:

var results = elasticClient.Search<User>(s => s
    .Index("user")
    .Query(q => q                    
        .Exists(e => e
            .Field("location")
        )
    )            
);

您可以按如下方式获取原始查询 JSON:

SearchDescriptor<User> debugQuery = new SearchDescriptor<User>()
    .Index("user")
    .Query(q => q                    
        .Exists(e => e
            .Field("location")
        )
    )
;

using (MemoryStream mStream = new MemoryStream())
{
    elasticClient.Serializer.Serialize(debugQuery, mStream);
    string rawQueryText = Encoding.ASCII.GetString(mStream.ToArray());
}

【讨论】:

    【解决方案5】:

    在发出请求之前,来自 Nest Query - For Nest 5.3.0 :

    var stream = new System.IO.MemoryStream();
    elasticClient.Serializer.Serialize(query, stream );
    var jsonQuery = System.Text.Encoding.UTF8.GetString(stream.ToArray());
    

    编辑:它是从 Nest 6.x 更改而来的,您可以执行以下操作:

    var json = elasticClient.RequestResponseSerializer.SerializeToString(request);
    

    【讨论】:

    • +1 用于获取请求正文在发送之前,但它在 6.x 中完全工作。 Serializer 更改为 RequestResponseSerializer。此外,还添加了SerializeToString,因此可以将整个内容简化为one-liner
    【解决方案6】:

    在嵌套版本 6 上使用

    connextionString.DisableDirectStreaming();
    

    然后在 response.DebugInformation 上可以看到所有信息。

    【讨论】:

    • 这是 2019 年更相关的答案
    【解决方案7】:

    使用result.ConnectionStatus.Request

    【讨论】:

    • 我试过了,但是字节数组中没有数据。你有如何使用它的例子吗?
    • 在实际代码中没有,但我经常使用它来调试 Visual Studio 中的查询。尝试在'result ='上设置断点,然后进行一步,然后看看你在result.ConnectionStatus中得到了什么。
    • ConnectionStatus 在 ISearchResponse 中不存在:\
    【解决方案8】:

    虽然可以通过代码获取原始请求/响应,但我发现使用 fiddler 分析它要容易得多。
    原因是我可以轻松地分析原始请求、响应、标头、完整 URL、执行时间 - 所有这些都无需任何代码更改的麻烦。

    以下是一些参考链接,以防不熟悉 fiddler 的人想要查看详细信息:
    #1 https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/logging-with-fiddler.html
    #2 NEST 1.0: See request on Fiddler
    #3 https://newbedev.com/how-to-get-nest-to-work-with-proxy-like-fiddler

    【讨论】:

      【解决方案9】:

      使用Fiddler 怎么样?! :)

      【讨论】:

        【解决方案10】:

        在使用 NEST 7 并且您不想启用调试模式时。

        public static string GetQuery<T>(this IElasticClient client, SearchDescriptor<T> searchDescriptor) where T : class
            {
                using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                {
                    client.RequestResponseSerializer.Serialize(searchDescriptor, ms);
        
                    return Encoding.UTF8.GetString(ms.ToArray());
                }
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-14
          • 2016-08-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-09
          相关资源
          最近更新 更多