从 NEST 客户端获取原始查询

Get raw query from NEST client

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

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

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

使用result.ConnectionStatus.Request.

您可以从 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.

在发出请求之前,从 Nest 查询 - 对于 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);

在 ElasticSearch 5.x 中,RequestInformation.Request 属性 在 ISearchResponse<T> 中不存在,但是 您可以生成原始查询 JSON 使用弹性客户端序列化器和 SearchDescriptor。例如,对于给定的 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());
}

对于 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));
});

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

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

如果您在 Visual Studio 中进行调试,可以方便地在此行之后放置一个断点,当您点击它时,将鼠标悬停在上面的 json 变量上并点击 magnifying glass thingy.您将获得 JSON.

的良好格式化视图

在 nest 版本 6 上使用

connextionString.DisableDirectStreaming();

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

使用 Fiddler 怎么样?! :)

虽然可以通过代码获取原始 request/response,但我发现使用 fiddler 分析它要容易得多。
原因是我可以轻松分析原始请求、响应、headers、完整 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

使用 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());
        }
    }