Mongo Aggregation:$ group和$ project数组以对象计数 [英] Mongo Aggregation : $group and $project array to object for counts
问题描述
我有类似的文件:
{
"platform":"android",
"install_date":20151029
}
- 平台-可以具有[android | ios | kindle | facebook]中的一个值.
- 安装日期-有很多安装日期
也有很多字段.
目标:我正在计算特定日期每个平台的安装量.
Aim : I am calculating installs per platform on particular date.
所以我在聚合框架中使用分组依据,并按平台进行计数.文档应如下所示:
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"
推荐答案
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 } }
])
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
将逻辑条件作为第一个参数(如果是),然后返回第二个参数(如果计算结果为true)(然后)或第三个参数(假)(否则).这会使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" ] },
为true,则表达式将计算为{ $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屋!