假设我的mongo架构如下所示:
db.events = [
{
"_id" : ObjectId("528cb8f06e95520dd7000004"),
"user_id" : "1",
"event_name" : "view",
"product_id" : 20
},
{
"_id" : ObjectId("528cb8f06e95520dd7000004"),
"user_id" : "1",
"event_name" : "like",
"product_id" : 20
},
{
"_id" : ObjectId("528cb8f06e95520dd7000004"),
"user_id" : "2",
"event_name" : "view",
"product_id" : 20
},
{
"_id" : ObjectId("528cb8f06e95520dd7000004"),
"user_id" : "1",
"event_name" : "buy",
"product_id" : 21
}
]
我想输出每个事件的计数,按用户和产品分组,例如:
[
{
"user_id" : 1,
"product_id" : 20,
"view_count" : 1,
"buy_count" : 0,
"like_count" : 1,
},
{
"user_id" : 1,
"product_id" : 21,
"view_count" : 0,
"buy_count" : 1,
"like_count" : 0,
},
{
"user_id" : 2,
"product_id" : 20,
"view_count" : 1,
"buy_count" : 0,
"like_count" : 0,
}
]
我陷入了最后一步,即“合并”一行中每个事件的计数。到目前为止我的解决方案:
db.events.aggregate([
{ $group: { // Group users and products, collects event names
_id: { user_id: '$user_id', product_id: '$product_id' },
events: { $addToSet: "$event_name" }
}},
{ $unwind : "$events" }, // unwind the events as document stream so they can be counted
{ $group : { // group and count by event name
_id : { user: "$_id.user_id", product: "$_id.product_id", action: "$events" },
count: { $sum: 1 }
}},
{ $project: { // rename some attributes...
_id: 0,
user_id: '$_id.user',
product_id: '$_id.product',
event_name: '$_id.action',
event_count: '$count'
}},
{ $group : { // finally group everything in one row
_id : { user: "$user_id", product: "$product_id"},
"$event_name" : { $sum: "$actions_with" } // ERROR group aggregate field name '$event_name' cannot be an operator name"
}}
]
);
答案 0 :(得分:8)
对此的聚合查询非常简单:
db.test.aggregate( [
{ $group: {
'_id' : { user_id: '$user_id', product_id: '$product_id' },
view_count: { $sum: {
$cond: [ { $eq: [ '$event_name', 'view' ] }, 1, 0 ]
} },
like_count: { $sum: {
$cond: [ { $eq: [ '$event_name', 'like' ] }, 1, 0 ]
} },
buy_count: { $sum: {
$cond: [ { $eq: [ '$event_name', 'buy' ] }, 1, 0 ]
} },
} },
{ $project: {
_id: 0,
user_id: '$_id.user_id',
product_id: '$_id.product_id',
view_count: 1,
like_count: 1,
buy_count: 1
} }
] );
然而,没有方法可以将任意数量的键(操作)分组 - 您的聚合查询需要全部指定它们。