mongodb - MongoDB聚合查询计算用户和支付模型分离时的ARPU
问题描述
我想编写一个聚合查询来计算 ARPU(每个用户的平均收入),但我被困在如何使用来自不同模型的数据,我知道我可以加入模型,$lookup
但我无法计算所有用户的数量方法。
这些是我的模型:
// User:
{
_id,
username: String,
os: String
}
和
// Payment:
{
_id,
user: ObjectId,
price: Number
}
我需要计算所有付款的总和除以所有用户的数量。
之后,我需要按操作系统对它们进行分组,即用户支付的所有款项的总和os='os1'
除以os='os1'
每个操作系统的所有用户数
编辑
例如,用户的样本数据是:
{
"_id" : ObjectId("5b77fdffcbbd830011dbc04e"),
"username" : "user1",
"os" : "android"
},
{
"_id" : ObjectId("5b7856756aaf56001120816b"),
"username" : "user2",
"os" : "android"
},
{
"_id" : ObjectId("5b824fa7234d1b0010310522"),
"username" : "user3",
"os" : "android"
},
{
"_id" : ObjectId("5b8a242444074c0074b8a318"),
"username" : "user4",
"os" : "ios"
},
{
"_id" : ObjectId("5b7801b0cbbd830011dbc050"),
"username" : "user5",
"os" : "ios"
}
付款的样本数据是:
{
"_id" : ObjectId("5bab61b617df7f173037fb1b"),
"user" : ObjectId("5b77fdffcbbd830011dbc04e"), // user1
"price" : 5
},
{
"_id" : ObjectId("5bad4f980ab23100119300ec"),
"user" : ObjectId("5b77fdffcbbd830011dbc04e"), // user1
"price" : 10
},
{
"_id" : ObjectId("5bad525edeed4e0011286842"),
"user" : ObjectId("5b7856756aaf56001120816b"), // user2
"price" : 5
},
{
"_id" : ObjectId("5bad525edeed4e0011286848"),
"user" : ObjectId("5b8a242444074c0074b8a318"), // user4
"price" : 5
},
{
"_id" : ObjectId("5bad525edeed4e0011286849"),
"user" : ObjectId("5b8a242444074c0074b8a318"), // user4
"price" : 15
}
我的预期输出是使用聚合查询实现的数字。
最初我想要的是每位用户的平均收入:
每用户平均收入: {sum of all payments} / {count of all users} = 40 / 5 = 8
如果我能做到这一点,那么我需要为每个操作系统对它们进行分组:
IOS-ARPU: {sum of payments ios users made} / {count of ios users} = 20 / 2 = 10
安卓ARPU: {sum of payments android users made} / {count of android usrs} = 20 / 3 = 6.67
- 请注意,有些用户可能没有支付任何费用,但在计算 ARPU 时需要将其计算在内。
解决方案
您可以从$lookup开始,然后使用$reduce计算totalPayments
每个用户。然后您可以$group bynull
以获取包含用户总数和总付款的单个文档。要获得 ARPU,您需要在最后一步中使用$divide 。
db.users.aggregate([
{
$lookup: {
from: "payments",
localField: "_id",
foreignField: "user",
as: "payments"
}
},
{
$project: {
_id: 1,
os: 1,
totalPayments: {
$reduce: {
input: "$payments",
initialValue: 0,
in: {
$add: [ "$$value", "$$this.price" ]
}
}
}
}
},
{
$group: {
_id: null,
totalUsers: { $sum: 1 },
totalPayments: { $sum: "$totalPayments" }
}
},
{
$project: {
arpu: { $divide: [ "$totalPayments", "$totalUsers" ] }
}
}
])
输出:{ "arpu" : 8 }
要获得每个操作系统的 arpu ,您只需要$group
:$os
{
$group: {
_id: "$os",
totalUsers: { $sum: 1 },
totalPayments: { $sum: "$totalPayments" }
}
}
印刷:
{ "_id" : "ios", "arpu" : 10 }
{ "_id" : "android", "arpu" : 6.666666666666667 }