Mongodb地图减少了琐碎的查询

时间:2013-04-14 10:07:04

标签: mongodb mapreduce

我有一张下面的地图:

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); };

}

然后我定义了以下内容:

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
         }
 }

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

感谢您的帮助。

-Lalit

2 个答案:

答案 0 :(得分:1)

  

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

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

这是MapReduce算法的预期行为。

答案 1 :(得分:0)

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

来自MongoDB MapReduce Documentation

  

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