我正在尝试创建一个 Mapreduce 函数,它将从集合中排除重复项。这是一个作业,我是 MongoDB 的新手,所以如果我的代码不是很“漂亮”,我深表歉意;另外,对于所有这些,我使用的是 MongoVUE。
我有一个名为 citys 的集合,每个文档都有一个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,而不是aggregate)。
我的想法:在我的 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)关于如何修改我现有的解决方案以使其工作的任何提示?