Elastic Search: Composite Aggregations with Cardinality in NEST

I'm using the composite and terms aggregations to get grouped results based on a given field. I'm also using Cardinality aggregation to get the overall count of the aggregation buckets.

Find below the request query I'm sending to get the corresponding response.

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"
      }
    }
  }

Response :

{
  ...,
  "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" : {...}
        },
        {...},
        {...},
        {...}
      ]
    }
  }
}

I used Kibana to check the query and it works fine for me.

However I'm not sure how to use this cardinality aggregator in my NEST object syntax.

Here is my code:

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);

I'd greatly appreciate any help.

Take a look at the writing aggregations documentation for the client; it has some suggestions for more terse object initializer syntax, such as using AggregationDictionary and &&ing aggregations to combine them.

Here's an example that matches the request query

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);

Great!! It worked.. Thanks a lot Russ.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.