Mongo Aggregation : $group 和 $project 数组作为计数对象 [英] Mongo Aggregation : $group and $project array to object for counts
问题描述
我有如下文件:
{
"platform":"android",
"install_date":20151029
}
- platform - 可以有一个来自 [android|ios|kindle|facebook] 的值.
- install_date - 有很多 install_dates
还有很多字段.
目标:我正在计算每个平台在特定日期的安装量.
Aim : I am calculating installs per platform on particular date.
所以我在聚合框架中使用 group by 并按平台进行计数.文档应如下所示:
So I am using group by in aggregation framework and make counts by platform. Document should look like like:
{
"install_date":20151029,
"platform" : {
"android":1000,
"ios": 2000,
"facebook":1500
}
}
<小时>
我做过这样的事情:
I have done like:
db.collection.aggregate([
{
$group: {
_id: { platform: "$platform",install_date:"$install_date"},
count: { "$sum": 1 }
}
},
{
$group: {
_id: { install_date:"$_id.install_date"},
platform: { $push : {platform :"$_id.platform", count:"$count" } }
}
},
{
$project : { _id: 0, install_date: "$_id.install_date", platform: 1 }
}
])
提供的文件如下:
{
"platform": [
{
"platform": "facebook",
"count": 1500
},
{
"platform": "ios",
"count": 2000
},
{
"platform": "android",
"count": 1000
}
],
"install_date": 20151027
}
问题:
将数组作为平台"投影到单个对象
Projecting array to single object as "platform"
推荐答案
使用 MongoDb 3.4 及更高版本,您可以利用 $arrayToObject
操作符来得到想要的结果.您需要运行以下聚合管道:
With MongoDb 3.4 and newer, you can leverage the use of $arrayToObject
operator to get the desired result. You would need to run the following aggregate pipeline:
db.collection.aggregate([
{ "$group": {
"_id": {
"date": "$install_date",
"platform": { "$toLower": "$platform" }
},
"count": { "$sum": 1 }
} },
{ "$group": {
"_id": "$_id.date",
"counts": {
"$push": {
"k": "$_id.platform",
"v": "$count"
}
}
} },
{ "$addFields": {
"install_date": "$_id",
"platform": { "$arrayToObject": "$counts" }
} },
{ "$project": { "counts": 0, "_id": 0 } }
])
<小时>
对于旧版本,请利用 $cond
运算符在 $group
管道步骤,用于根据平台字段值评估计数,如下所示:
For older versions, take advantage of the $cond
operator in the $group
pipeline step to evaluate the counts based on the platform field value, something like the following:
db.collection.aggregate([
{ "$group": {
"_id": "$install_date",
"android_count": {
"$sum": {
"$cond": [ { "$eq": [ "$platform", "android" ] }, 1, 0 ]
}
},
"ios_count": {
"$sum": {
"$cond": [ { "$eq": [ "$platform", "ios" ] }, 1, 0 ]
}
},
"facebook_count": {
"$sum": {
"$cond": [ { "$eq": [ "$platform", "facebook" ] }, 1, 0 ]
}
},
"kindle_count": {
"$sum": {
"$cond": [ { "$eq": [ "$platform", "kindle" ] }, 1, 0 ]
}
}
} },
{ "$project": {
"_id": 0, "install_date": "$_id",
"platform": {
"android": "$android_count",
"ios": "$ios_count",
"facebook": "$facebook_count",
"kindle": "$kindle_count"
}
} }
])
在上面,$cond
将逻辑条件作为它的第一个参数 (if),然后返回计算结果为 true (then) 的第二个参数或 false (else) 的第三个参数.这使得 true/false 返回 1 和 0 以分别提供给 $sum
.
In the above, $cond
takes a logical condition as it's first argument (if) and then returns the second argument where the evaluation is true (then) or the third argument where false (else). This makes true/false returns into 1 and 0 to feed to $sum
respectively.
例如,如果 { "$eq": [ "$platform", "facebook" ] },
为真,则表达式将计算为 { $sum: 1 }
否则它将是 { $sum: 0 }
So for example, if { "$eq": [ "$platform", "facebook" ] },
is true then the expression will evaluate to { $sum: 1 }
else it will be { $sum: 0 }
这篇关于Mongo Aggregation : $group 和 $project 数组作为计数对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!