使用MongoDB的map/reduce来按两个字段进行“分组”

20

我需要的东西比MongoDB文档中的例子稍微复杂一些,但我似乎无法理解它。

假设我有一个对象集合,形式如{date: "2010-10-10", type: "EVENT_TYPE_1", user_id: 123, ...}

现在我想要得到类似于SQL GROUP BY查询的结果,即按日期和类型分组。也就是说,我想知道每一天中每种事件的数量。此外,我希望通过user_id将其唯一化,即如果一个用户在同一天内有多个事件,则只计算一次。

我正在尝试使用map/reduce来实现这一点。

我的操作是:

db.logs.mapReduce( 
    function() { 
        emit(this.type, 1); 
    }, 
    function(k, vals) { 
        var total = 0; 
        for (var i = 0; i < vals.length; i++) 
            total += vals[i]; 
        return total; 
    }
)

现在我有一段很好地按类型分组的代码,但是如何同时按日期进行分组呢?似乎emit()中的键不能是数组(我想过使用emit([this.date, this.type], 1))。另外,我如何确保每个用户的唯一性?

我刚开始学习MongoDB,仍然难以掌握基本概念。此外,目前可用的文档很少。非常感谢更有经验的用户提供的任何帮助。谢谢!


CouchDB可以将数组作为键,只是说一下。 - dominic
1个回答

19

在MongoDB Cookbook中找到了一个非常好的解决方案 (之前不知道这个资源)。

http://cookbook.mongodb.org/patterns/unique_items_map_reduce/

基本上,要按多个键进行分组,需要使用dict而不是list(我之前尝试过)。另外,为了得到唯一的结果,需要进行两次map/reduce操作。


5
链接无效。对于任何有兴趣在几个字段上进行分组/发射的人,可以使用以下结构:emit({ date:this.date, type:this.type }, 1)。 - Michał Szkudlarek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接