Mongodb MapReduce连接字符串?

时间:2010-06-04 16:14:54

标签: javascript mongodb mapreduce

我见过的所有MongoDB MapReduce示例都涉及计数/添加数字。我需要组合字符串,看起来MapReduce是最好的工具。我有一个这种格式的大型MongoDB集合:

{name: userone, type: typeone}
{name: usertwo, type: typetwo}
{name: userthree, type: typeone}

每个名称只有一种类型,但名称不一定是唯一的。我希望最终得到一个集合,列出特定类型的所有名称,可以是逗号分隔列表,也可以是数组,如下所示:

 {type: typeone, names: userone, usertwo}
 {type: typetwo, names: userthree}

我试图使用MapReduce来实现这一目标。当一个类型只有一个用户时,我的功能正常工作。但是,当有多个用户时,“未定义”将存储在名称字段中。

我不是很擅长Javascript,而且我还在学习MongoDB,所以它可能是一个简单的数据类型或范围错误。

这是我的map和reduce函数。他们怎么了?

map = function() {
emit(this.user,{type:this.type});
}

reduce = function(key, values) {
var all="";
for(var i in values) {
all+=values[i]['type']+",";
}
return all;
}

1 个答案:

答案 0 :(得分:5)

在我看来,你正试图通过类型进行分组。如果是这样,你应该首先发射类型。从那里,它几乎和你的代码一样,但我冒昧地清理了一下。

请注意,reduce函数可以在较小的组上多次调用。因此,如果您在分片环境中使用了代码,则可能会获得额外的尾随逗号。有关详细信息,请参阅Reduce Function

<强>地图:

m = function(){ emit(this.type, {names:this.name}); }

<强>减少

r = function(key, values){
  var all = [];
  values.forEach(function(x){
    all.push(x.names)
  })
  return {"names": all.join(", ")};
}

用法

res = db.users.mapReduce(m,r); db[res.result].find()

<强>替代:

每个OP请求,这是一个返回名称数组而不是逗号分隔列表字符串的版本:

m = function () {
    emit(this.type, {names:this.name});
}

r = function (key, values) {
    var all = [];
    values.forEach(function (x) {all.push(x.names);});
    return {type:key, names:all};
}

f = function (w, r) {
    r.names = r.names[0];
    return r
}

res = db.users.mapReduce(m,r, {finalize:f}); db[res.result].find()

干杯!