Mat*_*ias 1 c# mongodb aggregation-framework .net-core mongodb-.net-driver
我正在尝试按集合中的多个属性对文档进行类型安全的分组。我发现问题不在于按多个属性本身进行分组,而是键是对象 ( new { }) 而不是字符串。
这有效:
collection.Aggregate().Group(x => x.Name, x => new { Name = x.Key, Count = x.Sum(s => 1) }).ToList();
Run Code Online (Sandbox Code Playgroud)
这不起作用:
collection.Aggregate().Group(x => new { Name = x.Name }, x => new { Name = x.Key.Name, Count = x.Sum(s => 1) }).ToList();
Run Code Online (Sandbox Code Playgroud)
错误是:
MongoDB.Driver.MongoCommandException:“命令聚合失败:字段“名称”必须是累加器对象。
当我将不起作用的查询转换为字符串时,我得到以下信息:
aggregate([{ "$group" : { "_id" : { "Name" : "$Name" }, "Name" : "$_id.Name", "Count" : { "$sum" : 1 } } }])
Run Code Online (Sandbox Code Playgroud)
我想这里的问题是这部分"Name" : "$_id.Name"。我该如何解决这个问题?
我目前使用的是 2.8.0 版的 mongodb 驱动程序。
实际上驱动程序在这里行为正确,但您遇到的是聚合框架中$group管道阶段的限制。该文件指出:
输出文档包含一个 _id 字段,其中包含不同的 group by key。输出文档还可以包含计算字段,这些字段保存按 $group 的 _id 字段分组的某些累加器表达式的值
因此,在您的情况下,您试图在_id没有任何累加器的情况下引用字段。
从逻辑的角度来看,您的查询似乎是相似的。第一个被翻译成:
{
"$group" : {
"_id" : "$Name",
"Count" : {
"$sum" : 1
}
}
}
Run Code Online (Sandbox Code Playgroud)
第二个将返回相同的数据,但您有一个对象作为分组键。要在 C# 中解决这个问题,您需要引入.First()将被转换为$first 的表达式,因此运行:
Col.Aggregate()
.Group(
x => new { Name = x.Name },
x => new { Name = x.First().Name, Count = x.Sum(s => 1) })
.ToList();
Run Code Online (Sandbox Code Playgroud)
将在数据库上运行以下查询:
{
"$group" : {
"_id" : {
"Name" : "$Name"
},
"Name" : {
"$first" : "$Name"
},
"Count" : {
"$sum" : 1
}
}
}
Run Code Online (Sandbox Code Playgroud)
它可以工作,但在逻辑上它返回与第一次聚合相同的数据
| 归档时间: |
|
| 查看次数: |
3405 次 |
| 最近记录: |