Mongodb映射减少琐碎查询

Mongodb映射减少琐碎查询,mongodb,mapreduce,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:\/

我有下面的地图:

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;
} 
db.test_views.mapReduce(mapFunction,reduceFunction,{out:{inline:1}})
现在,如果我按如下方式启动地图:

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;
} 
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"
}
然后,我再次启动map reduce,它会给出正确的结果

{
         "_id" : "testing@test.com",
         "value" : {
                 "count_checkout" : 2,
                 "count_landing" : 0
         }
 }
有谁能帮助我理解为什么它返回单个文档的映射,而不在reduce中进行计数

谢谢你的帮助

-拉里特

有谁能帮助我理解为什么它返回单个文档的映射,而不在reduce中进行计数

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


这是算法的预期行为。

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

从:

减少功能的要求:

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