MongoDB按types和date分组
我有一个带有简单文档的集合,用以下结构存储impressions
和conversions
impressions
/* 1 */ { "_id" : ObjectId("566f1ef857c1e6dd3123050a"), "path_id" : ObjectId("55944c1ebe244fd19cbf510b"), "data_type" : "impression", "created_at" : ISODate("2015-12-14T19:56:40.100Z"), "__v" : 0 } /* 2 */ { "_id" : ObjectId("566f1fc9ac964e6f327c55d6"), "path_id" : ObjectId("55944c1ebe244fd19cbf510b"), "data_type" : "conversion", "created_at" : ISODate("2015-12-14T20:00:09.972Z"), "__v" : 0 } /* 3 */ { "_id" : ObjectId("566f2896739f6afa4485f327"), "path_id" : ObjectId("562e594315ef3d8c3f05d219"), "data_type" : "impression", "created_at" : ISODate("2015-12-14T20:37:42.139Z"), "__v" : 0 } /* 4 */ { "_id" : ObjectId("566f28e5739f6afa4485f328"), "path_id" : ObjectId("562e594315ef3d8c3f05d219"), "data_type" : "impression", "created_at" : ISODate("2015-12-14T20:39:01.233Z"), "__v" : 0 }
我可以按data_type
进行分组和计数,但是我需要做的是按date
分组,然后对data_type
进行计数,以获得以下结果
[ { '_id': 'Y', 'conversions': 20, 'impressions': 2703, 'date': '2015-12-14' }, { '_id': 'Z', 'conversions': 10, 'impressions': 1703, 'date': '2015-12-13' } ]
我现在的代码是以下,但只有data_type
组我试图添加一个项目,按date重组,迄今没有运气。
var path_id = new mongoose.Types.ObjectId( req.body.path_id ); var match = { 'path_id': { $eq: path_id } }; var group = { '_id': '$data_type', 'count': { '$sum': 1 } } Hit.aggregate( [ { $match: match }, { $group: group } ], function( err, res ) { console.log( res ); } );
结果是
POST /api/hits/bypath 200 30ms - 15b [ { _id: 'conversion', count: 2 }, { _id: 'impression', count: 2703 } ]
任何人都可以指引我走向正确的道路。
先谢谢了
要按date进行嵌套组合,必须使用Date聚合运算符 $ dateToString 。
这是查询
db.hits.aggregate([ { "$project": { "created_at": { "$dateToString": { "format": "%Y-%m-%d", "date": "$created_at" } }, "data_type": true } }, { "$group": { "_id": { "data_type": "$data_type", "created_at": "$created_at" }, "count": { "$sum": 1 } } }, { "$group": { "_id": { "data_type": "$_id.data_type" }, "data":{ "$addToSet" : { count: "$count", date: "$_id.created_at" } } } } ])
如果您想通过基于条件的操作在组之前进行匹配,请在查询中添加以下内容
{ "$match": { "path_id": { "$eq": "<path_id>" } } }
您可以使用date汇总运算符来投影日/月/年字段,然后按它们进行分组
{ "$project": { "y": { "$year": "$created_at" }, "m": { "$month": "$created_at" }, "d": { "$dayOfMonth": "$created_at" }, "data_type" : 1 } }, { "$group": { "_id": { "year": "$y", "month": "$m", "day": "$d", "data_type": "$data_type" }, count: { "$sum": 1 } } }
并将以这种格式输出:
"_id": { "year": 2015, "month": 10, "day": 5, "data_type": "impression" }, count: 10
然后按date再次分组,以将这些types合并到一个文档中
{ "$group": { "_id": { "year": "$_id.year", "month": "$_id.month", "day": "$_id.day" }, types: {"$push":"$_id.data_type"}, counters: {"$push":"$count"} } }
这将导致这样的结果:
"_id": { "year": 2015, "month": 10, "day": 5 }, types: ["impression", "conversion"] counters: [10, 5]
可能有一个更优雅或更快(1组)的方式来做到这一点,虽然,我不知道。