如何计算组织旗下应用调用API产生的总账单费用?
计算指定组织旗下应用的总账单费用
集合结构说明
1. Organization集合
包含组织基本信息及关联的应用ID数组,示例文档:
{ "_id" : ObjectId("64b4b8bc3975804004fa81b4"), "id_app" : [ ObjectId("64b4b842a5831248e8a6b65c"), ObjectId("64b4b34f54106c24dc018992") ], "is_deleted" : false, "name" : "Org1", "desc" : "Org1 desc", "createdAt" : ISODate("2023-07-17T03:42:52.845+0000"), "updatedAt" : ISODate("2023-07-17T03:42:52.845+0000"), "__v" : NumberInt(0) }
2. Application集合
包含应用基本信息及关联的API ID数组,示例文档:
{ "_id" : ObjectId("64b4b34f54106c24dc018992"), "id_api" : [ ObjectId("64b4ac07c4784418986870dc"), ObjectId("64b4abcdc4784418986870d7") ], "is_deleted" : false, "name" : "app1", "desc" : "app1 desc", "createdAt" : ISODate("2023-07-17T03:19:43.573+0000"), "updatedAt" : ISODate("2023-07-17T03:19:43.573+0000"), "__v" : NumberInt(0) }
3. Apis集合
包含API的详细信息,示例文档:
{ "_id" : ObjectId("64b4abcdc4784418986870d7"), "is_deleted" : false, "name" : "api1", "desc" : "Api 1 desc", "URL" : "http://localhost:8080/api/api1", "field" : "edu", "createdAt" : ISODate("2023-07-17T02:47:41.849+0000"), "updatedAt" : ISODate("2023-07-17T02:47:41.849+0000"), "__v" : NumberInt(0) }
4. Billing集合
记录应用调用API产生的账单费用,示例文档:
{ "_id" : ObjectId("64b4c3d6068f5537e4bbd01b"), "is_deleted" : false, "cost1" : NumberInt(10), "cost2" : NumberInt(5), "cost3" : NumberInt(3), "id_app" : ObjectId("64b4b842a5831248e8a6b65c"), "createdAt" : ISODate("2023-07-17T04:30:14.646+0000"), "updatedAt" : ISODate("2023-07-17T04:30:14.646+0000"), "__v" : NumberInt(0) }
计算方法
通过MongoDB聚合管道关联多集合,汇总目标组织旗下所有应用的账单费用,具体实现如下:
聚合管道代码(以组织Org1为例)
db.Organization.aggregate([ // 筛选目标组织,排除已删除记录 { $match: { name: "Org1", is_deleted: false } }, // 将组织关联的应用ID数组拆分为单个文档 { $unwind: "$id_app" }, // 关联Billing集合,拉取该组织下所有应用的账单 { $lookup: { from: "Billing", localField: "id_app", foreignField: "id_app", as: "billing_records" } }, // 拆分账单记录数组为单个文档 { $unwind: "$billing_records" }, // 排除已删除的账单记录 { $match: { "billing_records.is_deleted": false } }, // 计算单条账单的总费用 { $addFields: { single_bill_total: { $add: [ "$billing_records.cost1", "$billing_records.cost2", "$billing_records.cost3" ] } } }, // 汇总所有账单的总费用 { $group: { _id: "$_id", org_name: { $first: "$name" }, total_cost: { $sum: "$single_bill_total" } } }, // 格式化输出字段 { $project: { _id: 0, 组织名称: "$org_name", 总账单费用: "$total_cost" } } ])
步骤解释
- $match:定位目标组织,过滤已删除的无效数据。
- $unwind:将组织的
id_app数组拆分成单条应用ID文档,方便后续关联。 - $lookup:关联Billing集合,获取每个应用对应的所有账单记录。
- $unwind:拆分账单数组,让每条账单成为独立文档,便于计算。
- $match:过滤已删除的账单,确保统计数据准确。
- $addFields:计算单条账单的总费用(累加cost1、cost2、cost3)。
- $group:按组织ID分组,汇总所有账单的总费用,同时保留组织名称。
- $project:调整输出字段名,让结果更直观易读。
扩展场景
- 按时间范围统计:可在第五步的
$match中添加时间条件,比如:"billing_records.createdAt": { $gte: ISODate("2023-01-01T00:00:00Z"), $lte: ISODate("2023-12-31T23:59:59Z") } - 动态费用字段求和:如果账单的费用字段不固定(如存在更多costN字段),可使用
$objectToArray和$filter动态提取费用字段后求和,避免硬编码字段名。
内容的提问来源于stack exchange,提问作者cauchuyennhocuatoi
相关产品推荐
相关产品推荐

