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

时间:2017-01-11 12:51:06

标签: elasticsearch nest

使用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值存储在私有字段中&#34; _hits&#34;: enter image description here

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

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

json不包含topHits结果:

enter image description here

我可以访问值,但我需要使用嵌套方法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;
                }
            }
   }

但如果我可以将所有信息都放在一个中,那将是非常有用的,就像我们在没有嵌套的情况下进行弹性搜索请求一样

你知道是否有办法吗?

1 个答案:

答案 0 :(得分:2)

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

然而,有时候,您可能想要自己管理,这听起来像是您想做的事情。在这些情况下,可以使用Elasticsearch.Net,它是Elasticsearch的低级客户端,并且在您对请求和响应建模的方式方面不受影响。

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

这是一个例子

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的响应。您可以在T中进行更改,将其反序列化为您选择的client.LowLevel.Search<T>()。例如,您可以使用

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

返回一个字符串,或

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

返回流等

相关问题