[英]Reproducing MongoDB's map/emit functionality in javascript/node.js (without MongoDB)
我喜欢MongoDB提供的用于执行映射/归约任务的功能,特别是mapper函数中的emit()。 没有MongoDB的情况下,如何在javascript / node.js中重现下面显示的地图行为?
[{ cust_id: "A123", amount: 500 }, { cust_id: "A123", amount: 250 }, { cust_id: "B212", amount: 200 }]
[{ "A123": [500, 200] }, { "B212": 200 }]
一个使它像Mongo的一句话一样简单的库emmit()会很不错,但是本机函数也可以做到。
Array.reduce可以满足您的需求。 这是文档: https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
我还建议您使用具有reduce&reduceRight的undescore.js(如第一条评论)。 http://underscorejs.org/#reduce
如果您只是想使用emit
语法,那是可能的。 扫描出函数体并传入新的发射函数。
function mapReduce(docs, m, r) {
var groups = {}
function emit(key, value) {
if (!groups[key]) { groups[key] = [] }
groups[key].push(value)
}
var fn = m.toString()
var body = fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))
var map = new Function('emit', body)
docs.forEach(function (doc) {
map.call(doc, emit)
})
var outs = []
Object.keys(groups).forEach(function (key) {
outs.push({ _id: key, value: r(key, groups[key]) })
})
return outs
}
编辑,忘记示例:
var docs = // from above
Array.sum = function (values) {
return values.reduce(function (a, b) { return a + b })
}
mapReduce(docs,
function () {
emit(this.cust_id, this.amount)
},
function (k, values) {
return Array.sum(values)
}
)
// [ { _id: 'A123', value: 750 }, { _id: 'B212', value: 200 } ]
我同意有很多很棒的lib方法可以做到这一点,并且使用Array方法很简单。 这是我的建议 。 这非常简单,仅使用forEach Array方法。 我已经完成了一个循环,但是还有许多其他方法。
最后,我没有做过减少,因为您没有要求这样做,但是我希望这会有所帮助。
function emit (key, value, data) {
var res = {}; out = [];
data.forEach(function (item) {
var k = item[key];
var v = item[value];
if (k !== undefined && v !== undefined) {
if (res[k] !== undefined) {
out[res[k]][k].push(v);
} else {
var obj = {};
res[k] = out.length;
obj[k] = [v];
out.push(obj);
}
}
});
return out;
}
var data = [{name: 'Steve', amount: 50},{name: 'Steve', amount: 400}, {name: 'Jim', amount: 400}];
emit('name', 'amount', data)) // returns [{"Steve":[50,400]},{"Jim":[400]}]
emit('amount', 'name', data)) // returns [{"50":["Steve"]},{"400":["Steve","Jim"]}]
我使用了一个对象来存储每个唯一条目的数组索引。 有很多版本。 可能比我的要好很多,但是以为我会给你一个普通的JS版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.