mongodbmapreduce每分钟文档计数由一个额外的category字段分隔

mqxuamgl  于 2021-06-01  发布在  Hadoop
关注(0)|答案(2)|浏览(317)

我有一个mongodb集合,其架构如下:

const MessageSchema = {
 message: {type: String},
 category: {type String, allowedValues: ['a', 'b', 'c', 'd', 'e']},
 createdAt: {type: Date}
}

这些消息文档以随机的时间间隔创建。我想创建一个图表所需的数据集,该图表绘制每个类别每分钟的消息数(count)。输出将是一个带有键的对象数组 time, a.count, b.count, c.count, d.count 以及 e.count . 生成的数据集应仅考虑上周的数据,而不考虑更晚的数据。
数据集可能相当大。
我想我可以用这个 db.collection.mapReduce . 我找到了一个解决方案,它适用于所有消息,但不按类别进行分隔。一个指向正确方向的指针将不胜感激。

e5njpo68

e5njpo681#

如果可以通过简单的聚合来实现这一点,则没有理由使用mapreduce:

db.messages.aggregate([
  {$match: { createdAt: { $gte: ISODate('2018-01-01') } }},
  {$group: {
        _id: {date: {$dateFromParts:{
                year: { $year: "$createdAt" },
                month: { $month: "$createdAt" },
                day: { $dayOfMonth: "$createdAt" },
                hour: { $dayOfMonth: "$createdAt" },
                minute: { $minute: "$createdAt" }
             }},
             category: "$category"
        },
        count: { $sum: 1 }
    }
  }
])
whhtz7ly

whhtz7ly2#

您可以通过匹配发生在 createdAt 然后按分组 category :

db.getCollection('messages').aggregate([{
        $match: { createdAt: { $gte: ISODate('2018-10-10') } }
    },
    {
        $group: {
            _id: {
                year: { $year: "$createdAt" },
                day: { $dayOfYear: "$createdAt" },
                minute: { $minute: "$createdAt" },
            },
            categories: { $push: "$category" }
        }
    },
    { $unwind: "$categories" },
    {
        $group: {
            _id: { interval: "$_id", category: "$categories" },
            count: { $sum: 1 }
        }
    },
    { 
        $group: {
            _id: "$_id.interval",
            category_count: {
                $push: { category: "$_id.category", count: "$count" }
            }
        }
    }
])

相关问题