具有嵌套聚合的{Elasticsearch NEST客户端

时间:2016-06-14 08:57:18

标签: .net elasticsearch f# aggregation nest

我正在使用NEST 2.3.2。我正在尝试使用嵌套聚合构建查询。基本上,我有一个带日志的索引,它有时间戳和结果代码。我想首先将这些日志放入几分钟的桶中,然后根据结果代码进一步对它们进行分类。

我有以下用于生成查询的F#代码。

/// Generate an aggregation to put buckets by result code
let generateAggregationByResultCode () =
    let resultAggregationName = "result_aggregation"
    let aggregationByResults = new TermsAggregation(resultAggregationName)
    aggregationByResults.Field <- new Field(Name = "Result")
    aggregationByResults.ExecutionHint <- new Nullable<TermsAggregationExecutionHint>(TermsAggregationExecutionHint.GlobalOrdinals);
    aggregationByResults.MinimumDocumentCount <- new Nullable<int>(0);
    aggregationByResults.Size <- new Nullable<int>(bucketSize);
    aggregationByResults.Missing <- "-128"
    aggregationByResults

/// Generate an aggregation to classify into buckets by minutes and then by result code
let generateNewDateHistogramByMinute () =
    let dateHistogramByMinute = new DateHistogramAggregation("by_minute")
    dateHistogramByMinute.Field <- new Field(Name = "OperationTime")
    dateHistogramByMinute.Interval <- new Union<DateInterval, Time>(DateInterval.Minute) // can also use TimeSpan.FromMinutes(1.0)
    dateHistogramByMinute.MinimumDocumentCount <- new Nullable<int>(0)
    dateHistogramByMinute.Format <- "strict_date_hour_minute"
    let innerAggregations = new AggregationDictionary()
    innerAggregations.[resultInnerAggregationName] <- new AggregationContainer(Terms = generateAggregationByResultCode ())
    dateHistogramByMinute.Aggregations <- innerAggregations
    dateHistogramByMinute

我使用此聚合来通过

设置请求
let dateHistogram = generateNewDateHistogramByMinute ()
let aggregations = new AggregationDictionary()
aggregations.[histogramName] <- new AggregationContainer(DateHistogram = dateHistogram)
(* ... code omitted ... *)
dslRequest.Aggregations <- aggregations

当我打印出请求时,聚合部分就像这样

"aggs": {
    "BucketsByMinutes": {
      "date_histogram": {
        "field": "OperationTime",
        "interval": "minute",
        "format": "strict_date_hour_minute",
        "min_doc_count": 0
      }
    }
  }

内部聚合完全丢失。有谁知道我应该如何正确构建请求?如何在返回响应时检索内部存储桶?我没有为此找到合适的属性或方法,文档基本上不存在。

1 个答案:

答案 0 :(得分:1)

我不确定为什么你没有在请求中看到内部聚合;我看到了以下内容,略有修改版本的内容

open Nest
open Elasticsearch.Net

type Document () =
    member val Name = "" with get, set

let pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"))
let settings = new ConnectionSettings(pool, new InMemoryConnection())

settings.DisableDirectStreaming()
        .PrettyJson()
        .OnRequestCompleted(fun response ->
            if (response.RequestBodyInBytes <> null)
            then
                Console.WriteLine("{0} {1} \n{2}\n", response.HttpMethod, response.Uri, Encoding.UTF8.GetString(response.RequestBodyInBytes));
            else Console.WriteLine("{0} {1} \n", response.HttpMethod, response.Uri);

            if (response.ResponseBodyInBytes <> null)
            then
                Console.WriteLine("Status: {0}\n{1}\n{2}\n", response.HttpStatusCode, Encoding.UTF8.GetString(response.ResponseBodyInBytes), new String('-', 30));
            else Console.WriteLine("Status: {0}\n{1}\n", response.HttpStatusCode, new String('-', 30));
        ) |> ignore

let client = new ElasticClient(settings)

/// Generate an aggregation to put buckets by result code
let generateAggregationByResultCode () =
    let bucketSize = 10
    let resultAggregationName = "result_aggregation"
    let aggregationByResults = new TermsAggregation(resultAggregationName)
    aggregationByResults.Field <- Field.op_Implicit("Result")
    aggregationByResults.ExecutionHint <- new Nullable<TermsAggregationExecutionHint>(TermsAggregationExecutionHint.GlobalOrdinals);
    aggregationByResults.MinimumDocumentCount <- new Nullable<int>(0);
    aggregationByResults.Size <- new Nullable<int>(bucketSize);
    aggregationByResults.Missing <- "-128"
    aggregationByResults

/// Generate an aggregation to classify into buckets by minutes and then by result code
let generateNewDateHistogramByMinute () =
    let dateHistogramByMinute = new DateHistogramAggregation("by_minute")
    dateHistogramByMinute.Field <- Field.op_Implicit("OperationTime")
    dateHistogramByMinute.Interval <- new Union<DateInterval, Time>(DateInterval.Minute) // can also use TimeSpan.FromMinutes(1.0)
    dateHistogramByMinute.MinimumDocumentCount <- new Nullable<int>(0)
    dateHistogramByMinute.Format <- "strict_date_hour_minute"
    dateHistogramByMinute.Aggregations <- AggregationDictionary.op_Implicit(generateAggregationByResultCode())
    dateHistogramByMinute

let request = new SearchRequest<Document>()
request.Aggregations <- (AggregationDictionary.op_Implicit(generateNewDateHistogramByMinute()))

let response = client.Search<Document>(request)

这会在控制台中产生以下内容

POST http://localhost:9200/_search?pretty=true 
{
  "aggs": {
    "by_minute": {
      "date_histogram": {
        "field": "OperationTime",
        "interval": "minute",
        "format": "strict_date_hour_minute",
        "min_doc_count": 0
      },
      "aggs": {
        "result_aggregation": {
          "terms": {
            "field": "Result",
            "size": 10,
            "min_doc_count": 0,
            "execution_hint": "global_ordinals",
            "missing": "-128"
          }
        }
      }
    }
  }
}

Status: 200
------------------------------

以上在您开发过程中可能很有用;当您准备好对Elasticsearch执行时,请从InMemoryConnection构造函数中删除ConnectionSettings,同时删除对.DisableDirectStreaming().PrettyJson().OnRequestCompleted(fun)的调用在ConnectionSettings