Elasticsearch: составные агрегаты с количеством элементов в NEST - PullRequest
1 голос
/ 11 апреля 2020

Я использую составные и термины агрегации для получения сгруппированных результатов на основе заданного поля. Я также использую агрегирование Cardinality для получения общего количества сегментов агрегации.

Ниже приведен мой запрос, который я отправляю для получения соответствующего ответа:

Request :

"aggs": {
    "myfield_comp_agg": {
      "aggs": {
        "myfield": {
          "aggs": {
            "myfield_tophits": {
              "top_hits": {
                "size": 1
              }
            }
          },
          "terms": {
            "field": "myfield",
            "size": 10
          }
        }
      },
      "composite": {
        "after": {
          "myfield_comp_terms_agg": ""
        },
        "sources": [
          {
            "myfield_comp_terms_agg": {
              "terms": {
                "field": "myfield"
              }
            }
          }
        ]
      }
    },
    "Count_agg": {
      "cardinality": {
        "field": "myfield"
      }
    }
  }

Ответ :

{
  ...,
  "aggregations" : {
    "Count_agg" : {
      "value" : 33
    },
    "myfield_comp_agg" : {
      "after_key" : {
        "myfield_comp_terms_agg" : "value10"
      },
      "buckets" : [
        {
          "key" : {
            "DocId_comp_terms_agg" : "value1"
          },
          "doc_count" : 1,
          "DocId" : {...}
        },
        {...},
        {...},
        {...}
      ]
    }
  }
}

Я использовал Kibana для проверки запроса, и он отлично работает для меня.

Однако Я не уверен, как использовать этот агрегатор кардинальности в моем синтаксисе объекта NEST.

Вот мой код:

var termsAggregation = new TermsAggregation(GetTermsAggregationName(aggregationField)) {
                Field = aggregationField,
                Size = takeCount
            };

            var topHitsAggregation = new TopHitsAggregation(GetTopHitsAggregationName(aggregationField)) {
                Size = aggregationFieldCount
            };                
            var termsAggregationContainer = new AggregationContainer {
                Terms = termsAggregation,
                Aggregations = topHitsAggregation
            };
            var subAggregations = new Dictionary<string, IAggregationContainer>() {
                { aggregationField, termsAggregationContainer}
            };

            var compositeKey = new Dictionary<string, object>() {
                { GetCompositeTermsAggregationName(aggregationField), aggregationSkipValue }
            };
            var termsSource = new TermsCompositeAggregationSource(GetCompositeTermsAggregationName(aggregationField)) {
                Field = aggregationField
            };
            var compositeAggregation = new CompositeAggregation(GetCompositeAggregationName(aggregationField)) {
                After = new CompositeKey(compositeKey),
                Sources = new List<TermsCompositeAggregationSource> { termsSource },
                Aggregations = subAggregations
            };

var searchRequest = new SearchRequest(request.IndexName)
            {
                From = request.SkipCount,
                Size = request.TakeCount
            };
searchRequest.Aggregations = compositeAggregation;
ElasticSearchClient.Search<T>(searchRequest);

Я был бы очень признателен за любую помощь.

1 Ответ

0 голосов
/ 15 апреля 2020

Ответ, опубликованный Руссом в комментарии.

Посмотрите на составление документации для клиента; у него есть некоторые предложения по более краткому синтаксису инициализатора объекта, например, использование AggregationDictionary и && ing агрегатов для их объединения.

Вот пример, который соответствует запросу запроса

var client = new ElasticClient();   

AggregationDictionary aggs = new CompositeAggregation("myfield_comp_agg")
{
    After = new CompositeKey(new Dictionary<string, object>
    {
        { "myfield_comp_terms_agg", string.Empty }
    }),
    Sources = new ICompositeAggregationSource[] 
    {
        new TermsCompositeAggregationSource("myfield_comp_terms_agg")
        {
            Field = "myfield"
        }
    },
    Aggregations = new TermsAggregation("myfield")
    {
        Field = "myfield",
        Size = 10,
        Aggregations = new TopHitsAggregation("myfield_tophits")
        {
            Size = 1
        }
    }
} && new CardinalityAggregation("Count_agg", "myfield");

var searchRequest = new SearchRequest("my_index")
{
    Aggregations = aggs
};

var searchResponse = client.Search<object>(searchRequest);

Спасибо за помощь. Сработало отлично.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...