0

我有一张下面的地图:

var mapFunction = function() {

if(this.url.match(/http:\/\/test.com\/category\/.*?\/checkout/)) {
var key=this.em;
var value = {
    url : 'checkout',
    count : 1,
    account_id:this.accId

}emit(key,value); };
if(this.url.match(/http:\/\/test.com\/landing/)) {
var key=this.em;
var value = {
    url : 'landing',
    count : 1,
    account_id:this.accId

}emit(key,value); };

}

然后我定义了 reduce 如下所示:

var reduceFunction = function (keys, values) {
var reducedValue = {count_checkout:0, count_landing:0};
for (var idx = 0; idx < values.length; idx++) {
    if(values[idx].url=='checkout'){
        reducedValue.count_checkout++;
    }
    else {
        reducedValue.count_landing++;
    }
}
return reducedValue;
} 

现在,假设我只有 1 条记录:

{
        "_id" : ObjectId("516a7cff6dad5949ddf3f7b6"),
        "ip" : "1.2.3.4",
        "accId" : 123,
        "em" : "testing@test.com",
        "pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
        "url" : "http://test.com/category/prr/checkout",
        "domain" : "www.test.com",
        "pgUdTs" : ISODate("2013-04-14T09:55:11.682Z"),
        "title" : "Test",
        "ua" : "Mozilla",
        "res" : "1024*768",
        "rfr" : "www.google.com"
}

现在,如果我触发我的地图减少,如下所示:

db.test_views.mapReduce(mapFunction,reduceFunction,{out:{inline:1}})

我得到以下结果返回:

{
          "_id" : "testing@test.com",
          "value" : {
                  "url" : "checkout",
                  "count" : 1,
                  "account_id" : 123
          }
  }

所以,它基本上是把地图还给我。现在,如果我为这个电子邮件 ID 添加另一个文档。最后它变成了下面的样子。

{
        "_id" : ObjectId("516a7cff6dad5949ddf3f7b6"),
        "ip" : "1.2.3.4",
        "accId" : 123,
        "em" : "testing@test.com",
        "pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
        "url" : "http://test.com/category/prr/checkout",
        "domain" : "www.test.com",
        "pgUdTs" : ISODate("2013-04-14T09:55:11.682Z"),
        "title" : "Test",
        "ua" : "Mozilla",
        "res" : "1024*768",
        "rfr" : "www.google.com"
}
{
        "_id" : ObjectId("516a7e1b6dad5949ddf3f7b7"),
        "ip" : "1.2.3.4",
        "accId" : 123,
        "em" : "testing@test.com",
        "pgLdTs" : ISODate("2013-04-11T18:30:00Z"),
        "url" : "http://test.com/category/prr/checkout",
        "domain" : "www.test.com",
        "pgUdTs" : ISODate("2013-04-14T09:59:55.326Z"),
        "title" : "Test",
        "ua" : "Mozilla",
        "res" : "1024*768",
        "rfr" : "www.google.com"
}

然后,我再次启动地图减少,它给了我正确的结果

{
         "_id" : "testing@test.com",
         "value" : {
                 "count_checkout" : 2,
                 "count_landing" : 0
         }
 }

任何人都可以帮助我理解为什么它会返回单个文档的地图并且不会在减少中进行计数。

感谢帮助。

-拉利特

4

2 回答 2

1

任何人都可以帮助我理解为什么它会返回单个文档的地图并且不会在 reduce 中进行计数。

Reduce 步骤将具有相同键的文档组合成一个结果文档。如果您的 Map 函数发出的数据中只有一个键,则数据已经“减少”并且不会调用 reduce()。

这是MapReduce算法的预期行为。

于 2013-04-14T22:16:50.180 回答
0

reduce 函数应该返回与 map 函数发出的相同类型的值对象。
就像您所经历的那样,当有一个与键关联的值时 - 根本不会调用 reduce 函数。

来自MongoDB MapReduce 文档

reduce函数的要求:
...
返回对象的类型必须与map函数发出的值的类型相同,以确保以下操作为真:
reduce(key, [ C, reduce(key, [ A, B ]) ] ) == reduce(key, [ C, A, B ])

于 2013-04-14T23:29:01.113 回答