使用mongodb映射reduce:\u id问题

使用mongodb映射reduce:\u id问题,mongodb,map,reduce,Mongodb,Map,Reduce,我有一个名为“事件”的集合,如下所示: { "_id" : ObjectId("4fd89f8d3cbec825d7000001"), "type" : "lms_course_view", "datetime" : ISODate("2011-12-23T12:55:00Z"), "user" : [ { "_id" : ObjectId("4fd89

我有一个名为“事件”的集合,如下所示:

{
        "_id" : ObjectId("4fd89f8d3cbec825d7000001"),
        "type" : "lms_course_view",
        "datetime" : ISODate("2011-12-23T12:55:00Z"),
        "user" : [
                {
                        "_id" : ObjectId("4fd89f8d3cbec825d7000000")
                }
        ]
}
另一个称为“用户”,如下所示:

{
        "_id" : ObjectId("4fd89f8d3cbec825d7000000"),
        "name" : "02ad1046f",

         (...)
}
我试图计算每个用户生成每个事件类型的次数。我正在尝试使用map reduce,但我不知道如何创建一个映射函数,该函数在发出用户名(存储在不同的集合中)的同时对事件进行迭代


有线索吗?是否可以使用map reduce?

由于您的用户名与
事件
集合分开存储,因此您仍然需要进行两次传递。我建议使用,然后第二次将
user[“\u id”]
转换为
user[“name”]
。聚合框架代码可能类似于:

db.events.aggregate(
    { $unwind: "$user" }, // breaks apart user array into separate documents
    { $group: {
        _id: { user: "$user._id", type: "$type" }
        count: { $sum: 1 }
    } }
);

您的模式对于所述用例的构造似乎很糟糕

我建议重新考虑它,并将用户名非规范化到事件集合中

我假设user字段是一个数组,因为可以有多个用户生成每个事件-在这种情况下,它仍然是一个数组,但每个元素将有两个字段-\u id像现在一样加上表示用户名的name。这是相对“安全的”,因为用户名不会经常更改(如果有)


一旦你有了这个模式,你可以选择使用MapReduce(将{user name,event type}作为键),或者你可以使用聚合框架(在2.1版中),就像@slee在他的回答中描述的那样。

这是可能的,但你必须做两个MapReduce,您可以找到一个示例。是否存在用户名不在事件集合中的原因?您可能会考虑对架构进行反规范化,以将名称添加到用户数组。我同意,我的模式对于我的用例来说是很差的。不管怎样,这就是我所拥有的,我会尽力充分利用它。正如@slee所说,我需要两次传球。太好了。它很好用。非常感谢你。我不知道聚合框架。实际上,我正在使用2.0版(来自ubuntu宇宙存储库)。