Map Reduce不会发出大量数据集

时间:2015-08-18 05:22:44

标签: 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.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
}

这是有道理的,因为地图缩小输入与对以下查询的回答相同

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

现在当我将map reduce job中的搜索字符串更改为“破坏s”时出现主要问题,显示的结果是

{
"results" : [ ],
"timeMillis" : 329,
"counts" : {
    "input" : 0,
    "emit" : 0,
    "reduce" : 0,
    "output" : 0
},
"ok" : 1
}
由于地图缩小输入不等于以下查询的答案

,因此

不会生成任何内容

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

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

1 个答案:

答案 0 :(得分:0)

您的流程在很多方面存在缺陷。

  1. 文字搜索无效

    您要求$text搜索查询与部分字词匹配,例如

     "breaking bad s"
     "breaking bad f"
    

    在每种情况下," s"和" f"这里被忽略了,因为它们不是一个完整的词。因此,唯一的条款是"打破"并且"坏"。我的意思是"条款" 这里反对"短语" ,因为"破坏" ,因为您使用的语法不会这样做,而只会查找术语。

    他们"可能"是短语,但一般来说,如果被搜索的数据包含" break"或者"坏"在任何其他组合中。

    我不知道你认为这些重要来自何处,但它肯定与非字#34无关。附在那里。

  2. 映射器也错误

    从上面开始,由于你在这里真正匹配的是"打破"并且"坏"作为单个单词,那么只检查那些"单词"存在于字符串中。他们当然会,但测试是错误的,应该这样写:

    map = function() {
        if ( /breaking|bad/.test(this.torrent_name) ) {
            emit(null,1);
        }
    };
    
  3. 还原错误

    更重要的是,除了"发出"如果失败了,减速器将永远不会被调用。使用mapReduce时,我们的想法就是所有人共同使用#34}。 _id值被发送到reducer以减少"减少"到一个值,然后返回。

    你写这篇文章的方式只是试图传递values实际上是一个数组。如果减速器已经点火,那么这会产生一个大的"错误,因为你只能返回一个"单个"值。事实上,这就是为什么它被称为"减少"阶段,因为你想"减少"将分组数据下移到一个公共点。

    所以我们再次将其重写为符合逻辑的东西:

    var reduce = function(key,values) {
        return Array.sum(values);
    };
    

    此处还注意到," out"来自映射器的发射数据必须与结果和类型相同" out"减速机也是如此。

    这是因为为了处理"大数据",mapReduce不会同时处理相同的分组键"而是#34;而是处理小"块" ;。所以来自" out"一个减速器,最终可以回到"在"作为进一步减少的价值之一。

  4. 所以最后如果你运行这个:

    res = db.torrents.mapReduce(
        map,
        reduce,
        { 
            "out": { "inline": 1 },
            "query": { "$text":{ "$search" :search } }
        }
    );
    

    你实际上可能只是得到一个明智的回应,告诉你它做了一些事情。

    但是当你进一步发展这一点时,请注意上面所说的内容并完整阅读documentation,这也解释了上面描述的要点。