我在Mongodb中有一组对象,每个对象都嵌入了一组值,例如:
[1.22, 12.87, 1.24, 1.24, 9.87, 1.24, 87.65] // ... up to about 150 values
是地图/减少了在嵌入式阵列中查找中位数(平均值)和模式(最常见值)的最佳解决方案吗?我问的原因是map和reduce都必须返回相同的(结构上)值集。看起来在我的情况下我想要接受一组值(数组)并返回一组两个值(中位数,模式)。
如果没有,最好的方法是什么?我想让它在rake任务中运行,如果那是相关的。这是一个过夜数据处理的事情。
答案 0 :(得分:0)
这里有关于预期产出的关键问题。你的问题并不是100%清楚你想要的。
你想要(A):
{ _id: "document1", value: { mode: 1.0, median: 10.0 } }
{ _id: "document2", value: { mode: 5.0, median: 150.0 } }
... one for each document
...或者你想要(B),所有阵列的所有组合的模式和中位数。
如果您打算(A),请仔细阅读M / R文档并了解其局限性。选项(A) 可以成为Map / Reduce,它也可以是一个大for
循环,其中“{1}}为”{摘要“收集甚至回到原来的收藏品。这可能更有效率。
答案 1 :(得分:0)
我首先阅读此http://www.mongovue.com/2010/11/03/yet-another-mongodb-map-reduce-tutorial/。
我想你想要
完成功能
可以在缩小后运行finalize函数。 这样的函数是可选的,对于许多map / reduce来说不是必需的 案例。 finalize函数接受一个键和一个值,然后返回一个 最终价值。
function finalize(key, value) -> final_value
您的 reduce 功能可能会 为同一个对象多次调用 。 使用finalize时 事情最后应该只做一次;例如 计算平均值。
答案 2 :(得分:-4)
我假设你想找到模式&每个文档的中位数,你可以用map reduce来做到这一点。在这种情况下,您计算中位数和& map函数中的mode和reduce将返回未触及的地图结果
map = function() {
var res = 0;
for (i = 0; i < this.marks.length; i++) {
res = res + this.marks[i];
}
var median = res/this.marks.length;
emit(this._id,{marks:this.marks,median:median});
}
reduce = function (k, values) {
values.forEach(function(value) {
result = value;
});
return result;
}
和本集合
{ "_id" : ObjectId("4f02be1f1ae045175f0eb9f1"), "name" : "ram", "marks" : [ 1.22, 12.87, 1.24, 1.24, 9.87, 1.24, 87.65 ] }
{ "_id" : ObjectId("4f02be371ae045175f0eb9f2"), "name" : "sam", "marks" : [ 1.32, 11.87, 12.4, 4.24, 9.37, 3.24, 7.65 ] }
{ "_id" : ObjectId("4f02be4c1ae045175f0eb9f3"), "name" : "pam", "marks" : [ 3.32, 10.17, 11.4, 2.24, 2.37, 3.24, 30.65 ] }
你可以通过
获得中位数 db.test.mapReduce(map,reduce,{out: { inline : 1}})
{
"results" : [
{
"_id" : ObjectId("4f02be1f1ae045175f0eb9f1"),
"value" : {
"marks" : [
1.22,
12.87,
1.24,
1.24,
9.87,
1.24,
87.65
],
"median" : 16.475714285714286
}
},
{
"_id" : ObjectId("4f02be371ae045175f0eb9f2"),
"value" : {
"marks" : [
1.32,
11.87,
12.4,
4.24,
9.37,
3.24,
7.65
],
"median" : 7.155714285714285
}
},
{
"_id" : ObjectId("4f02be4c1ae045175f0eb9f3"),
"value" : {
"marks" : [
3.32,
10.17,
11.4,
2.24,
2.37,
3.24,
30.65
],
"median" : 9.055714285714286
}
}
],
"timeMillis" : 1,
"counts" : {
"input" : 3,
"emit" : 3,
"reduce" : 0,
"output" : 3
},
"ok" : 1,
}