Search code examples
c#elasticsearchnest

ElasticSearch Aggregation on list Items


how to Aggregate by list item (hashtext )

here my code

public class Tweet
{
     public ulong id { get; set; }
     public string text { get; set; }
     [Nest.Nested]
     public List<hashtags> hashtags { get; set; }
}


public class hashtags
{ 
     public string hashtext { get; set; } 
}

my index data example like:

 "hashtags" : [
        {
          "hashtext" : "aaaa"
        },
        {
          "hashtext" : "bbbb"
        },
        {
          "hashtext" : "ccccc"
        }
      ],
    }



.Aggregations(childAggs => childAggs
                .Nested("project_tags", n => n
                    .Path(p => p.hashtags)
                    .Aggregations(nestedAggs => nestedAggs
                        .Terms("by_tags", t => t
                            .Field(f => f.hashtags.First().hashtext)
                    )
                )
            ))

How do I can an aggregation query only on hashtext property e.g. I want get all hashtext text with count

aaaa     3   times 
ccccc    5  times

Solution

  • What you have will work, so long as hashtext on hashtags is mapped as keyword datatype (or mapped as text datatype with fielddata enabled, with the caveats that come with doing this).

    Here's a working example

    private static void Main()
    {
        var defaultIndex = "my_index";
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    
        var settings = new ConnectionSettings(pool)
            .DefaultIndex(defaultIndex);
    
        var client = new ElasticClient(settings);
    
        if (client.IndexExists(defaultIndex).Exists)
            client.DeleteIndex(defaultIndex);
    
        var createIndexResponse = client.CreateIndex(defaultIndex, c => c
            .Mappings(m => m
                .Map<Tweet>(mm => mm
                    .AutoMap()
                )
            )
        );
    
        var bulkResponse = client.Bulk(b => b
            .IndexMany(new []
            {
                new Tweet 
                { 
                    id = 1, 
                    text = "foo",
                    hashtags = new List<hashtags>
                    { 
                        new hashtags { hashtext = "aaaa" },
                        new hashtags { hashtext = "bbbb" },
                        new hashtags { hashtext = "cccc" }
                    }
                }, 
                new Tweet
                {
                    id = 2,
                    text = "bar",
                    hashtags = new List<hashtags>
                    {
                        new hashtags { hashtext = "aaaa" },
                        new hashtags { hashtext = "bbbb" }
                    }
                },
                new Tweet
                {
                    id = 3,
                    text = "baz",
                    hashtags = new List<hashtags>
                    {
                        new hashtags { hashtext = "aaaa" },
                        new hashtags { hashtext = "cccc" }
                    }
                }
            })
            .Refresh(Refresh.WaitFor)
        );
    
        var searchResponse = client.Search<Tweet>(s => s
            .Size(0)
            .Aggregations(childAggs => childAggs
                    .Nested("hashtags", n => n
                        .Path(p => p.hashtags)
                        .Aggregations(nestedAggs => nestedAggs
                            .Terms("by_tags", t => t
                                .Field(f => f.hashtags.First().hashtext)
                            )
                        )
                    )
                )
            );
    
        var hashtagBuckets = searchResponse.Aggregations.Nested("hashtags").Terms("by_tags").Buckets;
    
        foreach(var bucket in hashtagBuckets)
        {
            Console.WriteLine($"{bucket.Key}\t{bucket.DocCount} times");
        }
    }
    
    public class Tweet
    {
        public ulong id { get; set; }
        public string text { get; set; }
        [Nested]
        public List<hashtags> hashtags { get; set; }
    }
    
    
    public class hashtags
    {
        [Keyword]
        public string hashtext { get; set; }
    }
    

    which writes the following to the console

    aaaa  3 times
    bbbb  2 times
    cccc  2 times