我正在尝试在我的一个MongoDB数据库集合上创建一个简单的map / reduce函数。 我得到数据但看起来不对。我不确定地图部分。我可以这样使用IF / ELSE吗?
更新
我想获得拥有这些文件的作者数量。换句话说,有多少作者拥有上传的文件,因此有多少作者没有文件。
集合中的对象如下所示:
{
"_id": {
"$id": "4fa8efe33a34a40e52800083d"
},
"file": {
"author": "john",
"type": "mobile",
"status": "ready"
}
}
map / reduce看起来像这样:
$map = new MongoCode ("function() {
if (this.file.type != 'mobile' && this.file.status == 'ready') {
if (!this.file.author) {
return;
}
emit (this.file.author, 1);
}
}");
$reduce = new MongoCode ("function( key , values) {
var count = 0;
for (index in values) {
count += values[index];
}
return count;
}");
$this->cimongo->command (array (
"mapreduce" => "files",
"map" => $map,
"reduce" => $reduce,
"out" => "statistics.photographer_count"
)
);
答案 0 :(得分:1)
地图部分对我来说没问题。我会略微改变减少部分。
values.forEach(function(v) {
count += v;
}
你应该不使用for in
循环来迭代数组,这并不意味着这样做。它用于枚举对象的属性。 Here is更详细的解释。
为什么您认为您的数据有误?您的源数据是什么?你得到了什么?你期望得到什么?
答案 1 :(得分:1)
我只是尝试了你的地图并减少了mongo shell并得到了正确的(合理的)结果。
你可以做你正在做的另一种方法是摆脱地图中的内部“if”条件,但是用适当的查询子句调用你的mapreduce函数,例如:
db.files.mapreduce(map,reduce,{out:'outcollection', query:{"file.author":{$exists:true}}})
或者如果碰巧有索引使查询有效,只需删除所有ifs并使用query:{"file.author":{$exists:true},"file.type":"mobile","file.status":"ready"}
子句运行mapreduce。更改条件以匹配您想要总结的实际案例。
在2.2(今天即将推出的版本为rc0)中,您可以使用聚合框架进行此类查询,而不是编写map / reduce函数,希望这会简化一些事情。