MongoDB .NET Core中按子对象属性求和结果排序问题求助
问题分析
原代码的核心问题有两个:
- 嵌套
Lookup写法错误,MongoDB的Lookup无法直接将关联结果写入已关联对象的嵌套字段(Template.Samples),需先完成Template的关联,再单独关联Samples并合并到Template中。 - 两次
Unwind后,Template.Samples已变成单个Sample对象而非集合,此时调用Sum会引发序列化错误;且Linq的Sum方法无法被MongoDB聚合框架正确解析为数据库端的聚合操作。
解决代码
以下是修正后的聚合代码,通过MongoDB聚合管道的原生操作完成求和与排序:
var data = _mongoDatabase.GetCollection<Instance>("Instance") // 关联Template集合 .Lookup("Templates", "TemplateId", "TId", @as: "Template") // 展开Template数组(每个Instance对应一个Template) .Unwind("Template") // 关联当前Template对应的Sample集合 .Lookup("Sample", "Template.TId", "TemplateId", @as: "Template.Samples") // 添加计算字段:对SampleData求和 .AddFields(new BsonDocument("TotalSampleData", new BsonDocument("$sum", "$Template.Samples.SampleData"))) // 按求和结果降序排序 .SortByDescending(x => x.TotalSampleData) // 转换为Instance类型 .As<Instance>() .ToList();
补充说明
- 如果需要在结果中保留求和字段
TotalSampleData,建议创建一个继承自Instance的DTO类,添加public long TotalSampleData { get; set; }属性,再将代码中的As<Instance>替换为As<InstanceWithTotal>。 - 避免在Linq的排序/筛选逻辑中使用内存集合操作(如
Sum),这类操作无法被MongoDB转换为数据库端的聚合命令,必须使用MongoDB聚合管道的原生操作符(如$sum)实现。
内容的提问来源于stack exchange,提问作者Rushi Sharma
相关产品推荐
相关产品推荐

