我有一个收藏ProductViews。
ProductViews
产品浏览
{ productId: '5b8c0f3204a10228b00a1745, createdAt: '2018-09-07T17:18:40.759Z', }
我有一个查询,用于获取特定产品的每日视图。
询问
ProductView.aggregate([ { $match: { productId } }, { $project: { day: { $substr: ["$createdAt", 0, 10] } } }, { $group: { _id: "$day", count: { $sum: 1 }, time: { $avg: "$createdAt" }, } }, { $sort: { _id: 1 } }, { $project: { date: '$_id', views: '$count', }, }, ]).exec((err, result) => ...)
当前结果
[ { date: '2018-09-01', views: 1 }, { date: '2018-09-02', views: 3 }, { date: '2018-09-04', views: 2 }, { date: '2018-09-05', views: 5 }, // ... ]
问题
问题是,这种聚合不会{ date: '2018-09-03', views: 0 }在有0视图的几天内返回。这会导致数据显示不正确:
{ date: '2018-09-03', views: 0 }
0
结果应该看起来像
[ { date: '2018-09-01', views: 1 }, { date: '2018-09-02', views: 3 }, { date: '2018-09-03', views: 0 }, { date: '2018-09-04', views: 2 }, { date: '2018-09-05', views: 5 }, // ... ]
PS:最好输入开始和结束日期以基于此范围输出结果
您需要几个额外的步骤来返回默认值。首先,你需要使用$group与_id设置为null收集所有结果中的一个文件内。然后,您可以将$ map与一组天作为输入。在其中,$map您可以使用$ indexOfArray查找当前结果集中是否存在该日期。如果是(index != -1),则可以返回该值,否则需要返回默认子文档,views并将其设置为0。然后,您可以使用$ unwind来获取文档列表,并使用$ replaceRoot来将嵌套提升stats到顶层。
$group
_id
null
$map
index != -1
views
stats
ProductView.aggregate([ { $match: { productId: '5b8c0f3204a10228b00a1745' } }, { $project: { day: { $substr: ["$createdAt", 0, 10] } } }, { $group: { _id: "$day", count: { $sum: 1 }, time: { $avg: "$createdAt" }, } }, { $sort: { _id: 1 } }, { $project: { date: '$_id', views: '$count', }, }, { $group: { _id: null, stats: { $push: "$$ROOT" } } }, { $project: { stats: { $map: { input: [ "2018-09-01", "2018-09-02", "2018-09-03", "2018-09-04", "2018-09-05" ], as: "date", in: { $let: { vars: { dateIndex: { "$indexOfArray": [ "$stats._id", "$$date" ] } }, in: { $cond: { if: { $ne: [ "$$dateIndex", -1 ] }, then: { $arrayElemAt: [ "$stats", "$$dateIndex" ] }, else: { _id: "$$date", date: "$$date", views: 0 } } } } } } } } }, { $unwind: "$stats" }, { $replaceRoot: { newRoot: "$stats" } } ]).exec((err, result) => ...)
您可以使用简单循环在应用程序逻辑中生成静态日期列表。我相信在MongoDB中也可以(使用$ range),但这可能会使此聚合管道复杂化。让我知道您是否满意,或者想尝试在MongoDB中生成该日期数组。