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)))
)
))));
什么都不管用。因此,我有两个问题:
组
和属性
)设置为未分析
,但找不到执行此操作的方法在阅读了几个小时的
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; }
}