如何通过MongoDB聚合查询返回指定课程的免费及付费文件计数
如何修改MongoDB聚合查询以统计课程的免费/付费文件数量
没问题,我来帮你调整这个MongoDB聚合查询,让它输出你想要的统计格式。你已经通过$lookup关联了Course和File集合,接下来只需要添加一个阶段来对关联后的files数组进行统计,替换成包含免费/付费文件计数的对象即可。
完整的聚合查询代码
Course.aggregate([ // 第一步:关联files集合,获取课程对应的所有文件 { $lookup: { from: "files", localField: "_id", foreignField: "courseId", as: "files" } }, // 第二步:统计免费和付费文件数量,替换原files数组 { $addFields: { files: { free: { $size: { $filter: { input: "$files", cond: { $eq: ["$$this.isFree", true] } } } }, paid: { $size: { $filter: { input: "$files", cond: { $eq: ["$$this.isFree", false] } } } } } } }, // 可选:如果只需要保留指定字段,添加这个阶段过滤 { $project: { _id: 1, name: 1, files: 1 } } ])
代码解释
- $lookup阶段:和你原来的查询一致,把当前课程对应的所有文件关联到
files字段中。 - $addFields阶段:
- 用
$filter从files数组中筛选出isFree: true的元素,再用$size获取数组长度,得到免费文件的数量free。 - 同理,筛选
isFree: false的元素并统计长度,得到付费文件的数量paid。 - 最后把原
files数组替换成包含这两个计数的对象。
- 用
- $project阶段(可选):如果你的Course集合有其他不需要返回的字段,可以用这个阶段只保留
_id、name和files字段。
另一种实现方式(使用$reduce)
如果你喜欢用累加的方式统计,也可以用$reduce来实现:
Course.aggregate([ { $lookup: { /* 同之前的配置 */ } }, { $addFields: { files: { $reduce: { input: "$files", initialValue: { free: 0, paid: 0 }, in: { free: { $add: ["$$value.free", { $cond: [{ $eq: ["$$this.isFree", true] }, 1, 0] }] }, paid: { $add: ["$$value.paid", { $cond: [{ $eq: ["$$this.isFree", false] }, 1, 0] }] } } } } } } ])
这种方式会遍历files数组的每个元素,根据isFree的值累加对应的计数,结果和上面的方法完全一致。
执行修改后的查询后,你就会得到期望的输出格式:
[ { "_id": "6161bdcc0aada09d81598840", "name": "Course1", "files": {"free": 1,"paid": 2} } ]
内容的提问来源于stack exchange,提问作者Gnanavel
相关产品推荐
相关产品推荐

