我正在尝试创建一个Mapreduce函数,它将从集合中排除重复项。这是一项任务,我是MongoDB的新手,所以如果我的代码不是很“漂亮”,我会道歉。另外,对于所有重要的事情,我正在使用MongoVUE。
我有一个名为 cities 的集合,每个文档都包含 CountryID 和 Name 字段。作业的第一部分包括编写一个MapReduce函数,该函数返回与给定国家/地区匹配的所有城市名称,保留重复项并计算城市数量。
我通过以下设置解决了这个问题:
db.runCommand({ mapreduce: "cities",
map : function Map() {
emit(
this.CountryID,
{ "citiesList" : [this.Name], "count" : 1 }
);
},
reduce : function Reduce(key, values) {
var reduced = {"citiesList" : [], "count" : 0};
values.forEach(function(val) {
reduced.citiesList.push(val);
reduced.count += val.count;
});
return reduced;
},
finalize : function Finalize(key, reduced) {
return reduced;
},
query : { "CountryID" : 15 },
out : { inline : 1 }
});
现在我应该改进我的答案,以排除重复项,计算新集合中的文档数量。我设法通过控制台使用db.cities.distinct("City", {"CountryID" : 15});
获取此信息(MongoVUE afaik不支持),但我似乎无法通过MapReduce获得解决方案(请注意我必须使用MapReduce ,而不是聚合)。
我的想法:在我的reduce函数中添加 if 条件,以便只推送列表中尚未存在的值。这就像是
values.forEach(function(val) {
if(!reduced.citiesList.contains(val)) { // val not contained
reduced.citiesList.push(val);
reduced.count += val.count;
}
});
这不起作用,我尝试使用 $ in 和 $ exists 运算符,但我显然没有做到这一点,并且MongoVUE并不是真的帮助(我没有收到任何错误消息?!)。
或者,我考虑在 finalize 函数中迭代我的列表并删除重复项,但我也找不到这样做的方法(注意:我想排除来自我的输出,而不是从集合中删除它们。)
我想知道的是:
a)我在这里走在正确的轨道上还是我弄错了?到目前为止,任务很简单,我可能会忽略一个简单的解决方案
b)有关如何修改现有解决方案以使其有效的任何提示?