elasticsearch,nest,C#,elasticsearch,Nest" /> elasticsearch,nest,C#,elasticsearch,Nest" />

C# 如何在弹性搜索中进行双嵌套聚合?

C# 如何在弹性搜索中进行双嵌套聚合?,c#,elasticsearch,nest,C#,elasticsearch,Nest,我有这样的数据结构: class SearchItem { public string Category { get; set; } public string SubCategory { get; set; } public string Description { get; set; } public double SalePrice { get; set; } public IList<SearchFilter> Filter

我有这样的数据结构:

class SearchItem
{
    public string Category { get; set; }
    public string SubCategory { get; set; }   
    public string Description { get; set; }
    public double SalePrice { get; set; }   
    public IList<SearchFilter> Filters { get; set; }      
}
class SearchFilter
{
    public string Group { get; set; }
    public string Attribute { get; set; }
}
因此,其他项可以具有相同的组名和属性值

我试图得到的结果:

Color
  --Red(18)
  --Yellow(5) 
Size
  --Medium(20)
  --Large(5)
这是我的映射:

i.Mappings(m =>
               m.Map<SearchItem>(map =>
                   map.AutoMap().Properties(p =>
                       p.Text(s => s.Name(n => n.Description).Analyzer("snowball"))
                       .Nested<SearchFilter>(
                       n=>n.Name(nn=>nn.Filters)
                           .Properties(pr => pr
                               .Text(t => t.Name(nn => nn.Attribute))
                               .Text(t => t.Name(nn => nn.Group)))
                       )    
                       ))));
什么都不管用。因此,我有两个问题:

  • 如何使用C#NEST进行此类聚合
  • 我想将嵌套字段(
    属性
    )设置为
    未分析
    ,但找不到执行此操作的方法

  • 在阅读了几个小时的
    Elastic 5.0
    文档后,我找到了答案:
    1) 对于嵌套属性,必须将小写。所以这里的错误是:
    “字段”:“filters.Group”
    。应该是
    “filters.group”

    2) 在Elastic 5.0中,我们没有对索引进行任何分析。Elastic团队删除了
    字符串
    类型,并添加了两个新类型(文本和关键字)。对于文本类型,默认情况下禁用聚合,如果要启用聚合,应设置
    FieldData=true
    。如果不想分析属性,我们应该使用
    关键字类型。因此,我的工作指标是:

     i.Mappings(m =>
                       m.Map<SearchItem>(map =>
                           map.AutoMap().Properties(p =>
                               p.Text(s => s.Name(n => n.Description).Analyzer("snowball"))
                               .Nested<SearchFilter>(
                               n=>n.Name(nn=>nn.Filters)
                                   .Properties(pr => pr
                                       .Keyword(t => t.Name(nn => nn.Attribute))
                                       .Keyword(t => t.Name(nn => nn.Group)))
                               )    
                               ))));
    
    i.Mappings(m=>
    m、 地图(地图=>
    map.AutoMap().Properties(p=>
    p、 Text(s=>s.Name(n=>n.Description).Analyzer(“雪球”))
    .嵌套(
    n=>n.Name(nn=>nn.Filters)
    .属性(pr=>pr
    .Keyword(t=>t.Name(nn=>nn.Attribute))
    .Keyword(t=>t.Name(nn=>nn.Group)))
    )    
    ))));
    
    如果有人坚持处理响应:

     class FilterGroup
        {
            public string Name { get; set; }
    
        public IList<FilterAttribute> Attributes { get; set; }
    
        public static IEnumerable<FilterGroup> CreateList(ISearchResponse<SearchItem> result)
        {
            return result.Aggs.Nested("filters").Terms("groups").Buckets.Select(g => new FilterGroup()
            {
                Name = g.Key,
                Attributes = g.Terms("attributes").Buckets.Select(x => new FilterAttribute()
                    {
                        Count = (int)x.DocCount,
                        Name = x.Key
                    }).ToList()
            });           
        }
    }
    
    class FilterAttribute
    {
        public string Name { get; set; }
        public int Count { get; set; }
    }
    
    类过滤器组
    {
    公共字符串名称{get;set;}
    公共IList属性{get;set;}
    公共静态IEnumerable CreateList(ISearchResponse结果)
    {
    返回result.Aggs.Nested(“filters”).Terms(“groups”).bucket.Select(g=>newfiltergroup()
    {
    名称=g.键,
    Attributes=g.Terms(“Attributes”).bucket.Select(x=>newfilteratAttribute()
    {
    Count=(int)x.DocCount,
    Name=x.Key
    })托利斯先生()
    });           
    }
    }
    类过滤器属性
    {
    公共字符串名称{get;set;}
    公共整数计数{get;set;}
    }
    

    希望对下一个潜水员有用

    您能否将您的编辑添加为答案并接受它?这将有助于其他人在未来将其视为一个答案。在序列化并发送到Elasticsearch时,默认情况下嵌套驼峰案例属性名称;此行为可通过
    连接设置
    完成上的
    .DefaultFieldNameInferrer()
    进行控制。谢谢你,罗斯,它起作用了。
    var result = _elasticClient.Search<SearchItem>(x =>
                        x.Sort(ss => ss.Ascending(ff => ff.Sequence)).Size(48)
                            .Query(q => q.Bool(b =>
                            b.Must(ConstructBaseQuery(search))))
                            .Aggregations(a => a                            
                               .Nested("filters", n => n
                                  .Path(p => p.Filters)
                                  .Aggregations(aa => aa.Terms("groups", t => t.Field(f => f.Filters.Suffix("Group"))))))); 
    
    {
      "size": 48,
      "sort": [
        {
          "sequence": {
            "order": "asc"
          }
        }
      ],
      "aggs": {
        "filters": {
          "nested": {
            "path": "filters"
          },
          "aggs": {
            "groups": {
              "terms": {
                "field": "filters.Group"
              }
            }
          }
        }
      },
      "query": {
        "bool": {
          "must": [
            {
              "multi_match": {
                "query": "modern tables",
                "operator": "and",
                "fields": [
                  "description"
                ]
              }
            }
          ]
        }
      }
    }
    
     i.Mappings(m =>
                       m.Map<SearchItem>(map =>
                           map.AutoMap().Properties(p =>
                               p.Text(s => s.Name(n => n.Description).Analyzer("snowball"))
                               .Nested<SearchFilter>(
                               n=>n.Name(nn=>nn.Filters)
                                   .Properties(pr => pr
                                       .Keyword(t => t.Name(nn => nn.Attribute))
                                       .Keyword(t => t.Name(nn => nn.Group)))
                               )    
                               ))));
    
     class FilterGroup
        {
            public string Name { get; set; }
    
        public IList<FilterAttribute> Attributes { get; set; }
    
        public static IEnumerable<FilterGroup> CreateList(ISearchResponse<SearchItem> result)
        {
            return result.Aggs.Nested("filters").Terms("groups").Buckets.Select(g => new FilterGroup()
            {
                Name = g.Key,
                Attributes = g.Terms("attributes").Buckets.Select(x => new FilterAttribute()
                    {
                        Count = (int)x.DocCount,
                        Name = x.Key
                    }).ToList()
            });           
        }
    }
    
    class FilterAttribute
    {
        public string Name { get; set; }
        public int Count { get; set; }
    }