elasticsearch NEST:不使用 bucket.TopHits() 直接获取 TopHits 结果

elasticsearch NEST : get TopHits result directly without using bucket.TopHits()

我正在使用 nest 进行术语聚合。

我也在做内部 TopHits 聚合。

我的结果给了我响应对象中的所有结果信息,除了 TopHits 值,我可以通过 TopHits() 方法读取这些信息。

我想直接在结果中获得 tophits 值,而不使用 NEST TopHits() 方法来读入 aggs。我希望所有数据都包含在信息中,就像我们在弹性搜索经典请求中一样。

这就是我实际做的事情:

我的聚合请求:

 var response = Client.Search<myclass>(s => s
                                     .Type("type")
                                      .Aggregations(a => a
                                        .Terms("code_bucket", t => t
                                         .Field("field_of_aggregation")
                                         .Size(30)
                                         .Order(TermsOrder.CountAscending)
                                         .Aggregations(a2 => a2
                                         .TopHits("code_bucket_top_hits", th => th.Size(20))
                                       )
                                       )));

我收到一个结果对象,我可以在其中访问除 TopHits 之外的所有信息。

如果我们检查结果,我们可以看到 TopHits 值存储在私有字段“_hits”中:

如果我对结果对象进行字符串化,我可以看到 TopHits 的总数,但是我看不到字段 _hits 所以我可以看到文件:

JavaScriptSerializer js = new JavaScriptSerializer();
string json = js.Serialize(response);

json不包含topHits结果:

我可以访问值,但我需要使用嵌套方法 TopHits():

var firstBucket= response.Aggs.Terms("code_bucket");
foreach (var bucket in firstBucket.Buckets)
            {
                var hits = bucket.TopHits("code_bucket_top_hits");
                foreach (var hit in hits.Documents<myclass>())
                {
                    var prop1= hit.prop1;
                    var prop2= hit.prop2;
                }
            }
   }

但是如果我可以将所有信息集中在一起,那将非常有用,就像我们在没有嵌套的情况下进行 elasticsearch 请求时所做的那样

你知道有没有办法?

NEST 是 Elasticsearch 的更高层次抽象,它使用强类型对每个请求和响应进行建模,提供流畅的对象初始化语法来构建请求,以及访问部分响应的方法,而无需处理 JSON 自己连载

但是,有时您可能想自己管理它,这听起来像是您想要做的。在这些情况下,可以使用 Elasticsearch.Net,它是 Elasticsearch 的低级客户端,并且在您如何建模请求和响应方面没有意见。

您可以在 Elasticsearch.Net 中使用客户端而不是 NEST,但是,好消息是 NEST 在幕后使用 Elasticsearch.Net 并且还通过 .LowLevel 公开了低级客户端属性 在 IElasticClient 上。为什么要在 NEST 上使用低级客户端而不是直接使用 Elasticsearch.Net?这样做的一个主要原因是您可以在需要时利用请求和响应的强类型,并利用 NEST 对 Json.NET 的使用进行序列化,但绕过它并在您 want/need到.

这是一个例子

var client = new ElasticClient();

var searchRequest = new SearchRequest<Question>
{
    Size = 0,
    Aggregations = new TermsAggregation("top_tags")
    {
        Field = "tags",
        Size = 30,
        Order = new[] { TermsOrder.CountAscending },
        Aggregations = new TopHitsAggregation("top_tag_hits")
        {
            Size = 20
        }
    }
};

var searchResponse = client.LowLevel.Search<JObject>("posts", "question", searchRequest);

// this will be of type JObject. Do something with it
searchResponse.Body

在这里,我可以使用 NEST 的对象初始化语法来构造请求,但使用低级客户端将响应反序列化为 Json.NET JObject。您可以通过在 client.LowLevel.Search<T>() 中更改它来反序列化为您选择的 T。例如,您可以使用

var searchResponse = client.LowLevel.Search<string>("posts", "question", searchRequest);

到return一个字符串,或者

var searchResponse = client.LowLevel.Search<Stream>("posts", "question", searchRequest);

到return一个流等