将MongoDB中的聚合操作转换为MapReduce



几天来,我一直在尝试将此查询转换为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"返回一份车牌列表和它们的计数器;然后在定稿中把它全部加起来。

// 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.com/a/27532153/13474284

我在这里找到了答案和一个非常好的解释:https://stackoverflow.com/a/27532153/13474284

我找不到一种方法来返回"reduce"中来自"map"的相同内容。由于它运行了几次,所以只得到了上一次迭代的结果。从链接中出现的方式来看,问题毫无困难地得到了解决。

最新更新