使用mongodb映射缩小:_id问题

时间:2012-11-22 17:33:10

标签: mongodb map reduce

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

{
        "_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函数,同时发出用户的名字(存储在不同的集合中)。

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

2 个答案:

答案 0 :(得分:1)

由于您的用户名与events集合分开存储,因此您无论如何都需要进行两次传递。我建议您使用Aggregation Framework,然后在第二次传递中将user["_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 }
    } }
);

答案 1 :(得分:0)

您的架构似乎很难为您所陈述的用例构建。

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

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

一旦你有了这个模式,你可以选择使用MapReduce(发出{用户名,事件类型}作为密钥),或者你可以像@slee在他的答案中描述的那样使用聚合框架(2.1+版本)。