1

我们的 MongoDB 数据库包含所有用户帐户的列表,其中每个新注册在帐户文档中都有一个“created_at”字段,其中包含当前创建日期和时间。

我们想知道每天或每天有多少新注册,所以将一个 MapReduce 查询放在一起为我们找出这个。

db.accounts.mapReduce(
    function() { 
        var date = this.created_at.toLocaleDateString(); 
        emit(date, 1);
    }, 
    function(key, values) {
        return values.length;
    },
    { out: "output" })

我们的第一次尝试在上面。1对于每个注册,它都会为该日期发出一个值。然后使用每个数组的长度来确定当天有多少注册。

然而,虽然结果大部分是正确的,但也存在明显的不准确之处。例如,当我们知道实际数字要高得多时,第一天给了我们一个两位数的价值。尽管对相同的数据进行了操作,但在第二次运行 map reduce 函数后,一些值发生了变化。

我们更改了函数,改为对数组的值求和(记住,它应该只包含1',因此与array.length.

db.accounts.mapReduce(
    function() {
        var date = this.created_at.toLocaleDateString(); 
        emit(date, 1);
    }, 
    function(key, values) {
        var sum = 0; 
        for(var i = 0; i < values.length; i++) { 
            sum += values[i];
        }; 
        return sum; 
    },
    { out: "output" })

令我们惊讶的是,这为之前错误的每个日期提供了正确的结果。

有谁知道为什么第一个 map reduce 没有按预期运行?

4

1 回答 1

2

对于发出的值,Reduce 可能会被多次调用,随后的调用将传递给先前对 reduce 的调用的输出。当您只查看数组的长度时,您会错过这样一个事实,即您可能正在查看部分聚合的数据。对这些值求和将使较早的聚合累积,这就是您想要的。

于 2012-05-23T16:46:59.917 回答