Mongodb Map Reduce不会发出大数据集

Mongodb Map Reduce不会发出大数据集,mongodb,mapreduce,mongodb-query,Mongodb,Mapreduce,Mongodb Query,我在map reduce中遇到了一些问题,每当预期结果数据集很大时,它都不会返回任何内容,它适用于小数据集,比如4万个文档。以下是代码和问题理解。看,我用了这个密码 search = "breaking bad f" var emit = function(a,b){ print(a); } map = function() { if(this.torrent_name.indexOf(search) > -1){ emit(this._id, this

我在map reduce中遇到了一些问题,每当预期结果数据集很大时,它都不会返回任何内容,它适用于小数据集,比如4万个文档。以下是代码和问题理解。看,我用了这个密码

search = "breaking bad f"

var emit = function(a,b){
    print(a);
}

map = function() {
    if(this.torrent_name.indexOf(search) > -1){
        emit(this._id, this.torrent_name);
    }

}

reduce = function(key,values){
    return values;
}

res = db.torrents.mapReduce(map,reduce,{out: { inline: 1 },query:{$text:{$search:search}},scope:{search:search},sort:{'seeders':-1}})

printjson(res);
现在,此作业的结果是:

{
"results" : [ ],
"timeMillis" : 503,
"counts" : {
    "input" : 39859,
    "emit" : 0,
    "reduce" : 0,
    "output" : 0
},
"ok" : 1
}
这是有意义的,因为MapReduce输入和下面查询的答案相同

db.torrents.find({$text:{$search:"breaking bad f"}}).count()
output => 39859 
现在,当我将MapReduceJob中的搜索字符串更改为“breaking bad s”时,主要问题出现了,结果如下

{
"results" : [ ],
"timeMillis" : 329,
"counts" : {
    "input" : 0,
    "emit" : 0,
    "reduce" : 0,
    "output" : 0
},
"ok" : 1
}
这并不意味着什么,因为map reduce输入不等于下面查询的答案

db.torrents.find({$text:{$search:"breaking bad s"}}).count()
output => 71484

从上面的结果我得出结论,有记忆问题,但我不知道在哪里和为什么。请帮助。

您的流程在很多方面都有缺陷

  • 文本搜索不是这样工作的

    您要求搜索查询匹配部分单词,例如

    “断开坏s”
    “打破坏f”
    
    在每种情况下,这里的“s”和“f”都会被忽略,因为它们不是一个完整的单词。因此,人们只寻找“破坏”和“坏”这两个词。我的意思是“术语”这里a与“词组”相对,如“breaking bad”,因为您使用的语法不这样做,而是只查找术语

    它们“可能”是短语,但通常情况下,如果正在搜索的数据在任何其他组合中包含“破坏”或“错误”,它们就不会是短语

    我不知道你认为这些计数是从哪里来的,但它肯定与附加在那里的“非单词”无关

  • 映射器也错了

    从上面开始,由于您在这里实际匹配的是作为单个单词的“breaking”和“bad”,因此只检查字符串中是否存在这些“单词”是有意义的。它们当然是,但测试是错误的,应该这样写:

    map=function(){
    if(/breaking | bad/.test(this.torrent_name)){
    emit(null,1);
    }
    };
    
  • 减速器也有问题

    更重要的是,除了“emits”更早失效外,根本不会调用reducer。使用
    mapReduce
    的思想是将所有“公共”
    \u id
    值发送到reducer,以便“还原”为单个值,然后返回

    您编写此文件的方式只是尝试传递
    ,它实际上是一个数组。如果减速器已启动,则会产生一个“大”错误,即只能返回一个“单个”值。这就是为什么它被称为“减少”阶段的原因,因为您希望将分组数据“减少”到单个公共点

    因此,我们再次将其改写为符合逻辑的内容:

    var reduce=函数(键、值){
    返回Array.sum(值);
    };
    
    这里还要注意的是,从映射器发出的数据中“出来”的内容必须与从减速器中“出来”的内容具有相同的结构和类型

    这是因为为了处理“大数据”,mapReduce不会“一次”处理同一个分组键,而是处理小“块”。所以,从减速器中“输出”的数据,最终可能会作为要进一步减速的值之一“返回”

  • 因此,最后,如果您运行以下命令:

    res=db.torrents.mapReduce(
    地图,
    减少
    { 
    “out”:{“inline”:1},
    “查询”:{“$text”:{“$search”:search}
    }
    );
    
    你可能会得到一个理智的回答,告诉你它做了什么


    但是,当您进一步了解这一点时,请记下上面所说的内容,并充分阅读,其中也解释了上面所述的要点。

    好的,谢谢您的回答,但这没有什么帮助。即使将s改为季节,f改为第一,问题仍然是一样的。即使我将test从“indexOf”更改为正则表达式“I”(或)运算符,问题仍然是一样的。我已经知道你提到的那些事情,但是,那只是一个测试脚本,你提到的事情与我面临的问题无关。好像你忘了理解我在这里面临的主要问题。@rawat0419这是什么主要问题?如上所述,您的所有过程都是无效的,因此您不会得到结果。1.正确匹配并理解这是什么。2.主消息是“正确发射”,仅发射
    \u id
    ,另一个字段肯定不是您想要的mapReduce。3.正确地进行Reduce,如果调用了reducer,那么编写的reducer只会出错。如果你愿意,你可以告诉我你“理解”,但你随问题一起提交的清单表明情况并非如此。这就是答案。与尺寸无关。MapReduce的处理比您拥有的要大得多。好吧,您是说我没有得到结果的原因是我的mapper和reducer写错了。我明白了。但在这种情况下,它不应该在两种情况下都给出结果,它给出了“打破坏习惯”的预期结果,而不是“打破坏习惯”@rawat0419你的问题并没有问这个。它有两个带有“不完整”字符串的文本搜索,也不使用“短语”。如果你想知道如何得到“打破坏季”或“打破坏插曲”的结果,那么。从我的角度来看,你需要了解的第一件事是所有你做得不正确的事情,给你一些能产生“结果”的东西,而不是你目前得到的“什么都没有”。看看你问题的标题和你真正问的问题。@rawat0419此外,除此之外,我真的看不出你的问题是什么。把“不工作”变成“工作”是我在这里看到的唯一目标。我怀疑你真正想要的东西,根本不应该需要mapReduce。因此你的境况更好。在这里你学到了一些东西。我希望如此。