c# ElasticSearch NEST 聚合:分组

Posted

技术标签:

【中文标题】c# ElasticSearch NEST 聚合:分组【英文标题】:c# ElasticSearch NEST aggregation: group by 【发布时间】:2020-11-05 18:52:33 【问题描述】:

我的 ES NEST 查询有问题。它“创建组”,但项目列表为空。 我查找了示例并阅读了我发现的内容,但结果仍然是空的。

这是我的查询:

public partial class ElasticSearchService
    
        private const string groupBySubCategoryKey = "SubCategoryKey";

        public async Task SiteMap()
        
            ISearchResponse<AdvertisementObjectEntityExtended> result = await Client.SearchAsync<AdvertisementObjectEntityExtended>(s => s
               .Index(ElasticClientFactorySettings.AdvertisementObjectIndex)
               .Aggregations(agr =>
                agr.Terms(groupBySubCategoryKey,
                    g => g.Field(f =>
                        f.SubCategoryKey))));

            var r = result.Aggregations.Terms(groupBySubCategoryKey);
       

public static class ElasticClientFactory
    
        public static async Task<ElasticClient> ClientAsync(ElasticSearchSettings settings)
        
            Uri uri = new Uri($"settings.EndPoint");

            ConnectionSettings ConnectionSettings = new ConnectionSettings(uri)
                                                    .DefaultIndex(ElasticClientFactorySettings.AdvertisementObjectIndex)
                                                    .DefaultMappingFor<AdvertisementObjectEntityExtended>(i => i.IndexName(ElasticClientFactorySettings.AdvertisementObjectIndex))
                                                    .EnableHttpCompression()
                                                    .PrettyJson();

            ElasticClient client =  new ElasticClient(ConnectionSettings);

            CreateIndexResponse createIndexResponse = await client.Indices.CreateAsync(ElasticClientFactorySettings.AdvertisementObjectIndex, c => c
                .Map<AdvertisementObjectEntityExtended>(m => m
                    .AutoMap()
                    .Properties(p => p
                         .Text(t => t.Name(n => n.Id).Analyzer(AnalyzerSettings.No))
                         .Text(t => t.Name(n => n.UserUniq).Analyzer(AnalyzerSettings.NotAnalyzed))
                         .Text(t => t.Name(n => n.Uniq).Analyzer(AnalyzerSettings.NotAnalyzed))
                         .Text(t => t.Name(n => n.MainCategoryKey).Analyzer(AnalyzerSettings.NotAnalyzed))
                         .Text(t => t.Name(n => n.SubCategoryKey).Analyzer(AnalyzerSettings.NotAnalyzed))
                         .Nested<List<string>>(n => n.Name(nn => nn.Images)
                        )
                    )
                )
            );

            return client;
        
    

public partial class ElasticSearchService : IElasticSearchService
    
          public  ElasticSearchService(IOptions<ElasticSearchSettings> settings)
        
            Client = ElasticClientFactory.ClientAsync(settings.Value).Result;
        
    

有什么想法吗? 谢谢

【问题讨论】:

【参考方案1】:

问题是您的映射是文本类型。

要在文本字段上进行术语聚合,您需要为该字段打开 fielddata。 https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#CO255-1

但您可能真正想要的是使用关键字字段而不是文本,它会自动与术语聚合一起使用。默认情况下不对其进行分析。因此,对映射的以下更改应该可以解决问题:

    .Keyword(t => t.Name(n => n.Id))
    .Keyword(t => t.Name(n => n.UserUniq))
    .Keyword(t => t.Name(n => n.Uniq))
    .Keyword(t => t.Name(n => n.MainCategoryKey))
    .Keyword(t => t.Name(n => n.SubCategoryKey))

现在我应该补充一点,如果图像是字符串列表,则不需要进行嵌套映射。字符串列表基本上与 elasticsearch 中的单个字符串相同,因此您可以执行以下操作:

    .Keyword(t => t.Name(n => nn.Images))

【讨论】:

结果我得到了 2 个桶,桶中有 value 属性是长度为 0 的集合! 术语聚合仅返回每个唯一术语及其计数。你会想要像result.Aggregations.Terms(groupBySubCategoryKey).Buckets 这样的东西,每个桶都有一个Key 字段和一个DocCount 字段。 他们在那里,但我可能做错了,因为我也需要集合中的分组项目,但我得到的 DocCount 不是 0,但没有元素,我需要元素,类似于带有 lambda 表达式的 GroupBy。 elasticsearch 并不是执行 map/reduce/group by 操作的最佳工具。如果您无论如何都需要每个元素,您可以发出搜索以获取所有内容并在弹性搜索之外进行分组。或者您可以进行聚合,然后为每个组发出搜索。或者,如果您想在 1 个请求中完成所有操作,您可以在当前请求之上使用 Top Hits 聚合。 elastic.co/guide/en/elasticsearch/reference/current/…

以上是关于c# ElasticSearch NEST 聚合:分组的主要内容,如果未能解决你的问题,请参考以下文章

从 NEST C# 嵌套聚合中获取 Elasticsearch 结果

滚动或分页 Elasticsearch 聚合 - Nest 框架

NEST 搜索整个文档 C# Elasticsearch

使用 Elasticsearch NEST C# 索引 Json 文档

使用 C# 中的 NEST 库调用 elasticsearch 时,如何向 linq 语句添加条件逻辑?

Elasticsearch NEST – Examples for mapping between Query and C#