几天来,我一直试图将这个查询翻译成MapReduce。具体来说,我需要计算出有多少辆不同的汽车行驶了 "N "公里。
查询。
db.adsb.group({
"key": {
"KM": true
},
"initial": {
"countCar": 0
},
"reduce": function(obj, prev) {
if (obj.Matricula != null) if (obj.Matricula instanceof Array) prev.countCar += obj.Matricula.length;
else prev.countCar++;
},
"cond": {
"KM": {
"$gt": 10000,
"$lt": 45000
}
}
});
Mongo中的每个文档都有这样的形式
{
"_id" : ObjectId("5a8843e7d79a740f272ccc0a"),
"KM" : 45782,
"Matricula" : "3687KTS",
}
我想得到这样的结果:
/* 0 */
{
“KM” : 45000,
“total” : 634
}
/* 1 */
{
“KM” : 46000,
“total” : 784
}
我的代码在下面, 它编译,但没有给我预期的结果。
特别是,每次我输入'reduce'时,它似乎将所有的值重置为0,这使我无法累积注册.我的一个问题是,当处理大量信息时,函数必须迭代几次'reduce'.我也不知道是否可以这样做,或者我需要在'reduce'中返回车牌和他们的计数器的列表;然后在finalize中将其全部加起来。
// Map function
var m = function() {
if (this.KM > 10000 && this.KM < 45000) { // So that i can get KM grouped together by thousands (10000, 20000, 30000...)
var fl = Math.round(this.KM / 1000) * 1000;
var car = this.Matricula
emit (fl, car);
//print("map KM=" + fl + " Matricula= " + car);
}
};
// Reduce function
var r = function(key, values) {
var ya_incluido = false;
var cars_totales = 0;
var lista_car = new Array();
//print( key + " ---- " + values);
for (var i=0; i < values.length;i++)
{
for (var j=0; j < lista_car.length;j++)
{
if(values[i] == lista_car[j]) { //If it is already included, don't aggregate it
ya_incluido = true;
}
} if (ya_incluido != true) { //If it is not included, add it to lista_av list.
lista_car.push(values[i]);
} ya_incluido = false;
}
cars_totales = lista_av.length; //The number of distinct cars is equal to the lenght of the list we created
return cars_totales;
};
// Finalize function
var f = function(key,value) {
// Sum up the results?
}
db.runCommand( {
mapReduce: "dealer",
map: m,
reduce: r,
finalize: f,
out: {replace : "result"}
} );
我在这里找到了答案和一个非常好的解释。 https:/stackoverflow.coma2753215313474284。
我在这里找到了答案和一个非常好的解释。https:/stackoverflow.coma2753215313474284
我找不到一种方法,在'reduce'中返回与'map'相同的东西。而且由于它被运行了几次,它只得到了最后一次迭代的结果。链接中出现的方式,这个问题就不难解决了。