Mapreduce CouchDB视图-将重复键值减少/分组到数组

Mapreduce CouchDB视图-将重复键值减少/分组到数组,mapreduce,couchdb,Mapreduce,Couchdb,我的沙发数据库中有一个视图,它以以下格式输出数据: {"rows":[ {"key":["Partner1","Voucher Type 1"],"value":true}, {"key":["Partner1","Voucher Type 2"],"value":true}, {"key":["Partner2","Voucher Type 1"],"value":true}, {"key":["Partner3","Voucher Type 1"],"value":true}, {"key"

我的沙发数据库中有一个视图,它以以下格式输出数据:

{"rows":[
{"key":["Partner1","Voucher Type 1"],"value":true},
{"key":["Partner1","Voucher Type 2"],"value":true},
{"key":["Partner2","Voucher Type 1"],"value":true},
{"key":["Partner3","Voucher Type 1"],"value":true},
{"key":["Partner4","Voucher Type 1"],"value":true}
]}
我想做的是有效地“分组”合作伙伴|凭证类型, 因此,在上面的示例中,它将返回如下内容:

Partner1: ["Voucher Type 1", "Voucher Type 2"]
Partner2: ["Voucher Type 1"]
Partner3: ["Voucher Type 1"]
Partner4: ["Voucher Type 1"]
目前,我的地图缩小功能如下所示:

{"rows":[
{"key":"Partner1","value":["Voucher Type 2","Voucher Type 1"]},
{"key":"Partner2","value":["Voucher Type 1"]},
{"key":"Partner3","value":["Voucher Type 2"]}
]}
地图:

减少:

function(keys, values) {
    return true;
}
我正在查询
group=true


我怀疑我需要在reduce函数中做更多的工作?

考虑以下设计文档:

{
“_id”:“_设计/ddoc”,
“意见”:{
“合作伙伴”:{
“地图”:功能(文档){
发出(doc.PartnerName、doc.VoucherType);
},
“减少”:功能(键、值){
var voucherTypes=[];
值。forEach(函数(v){
voucherTypes=voucherTypes.concat(v);
});
返回凭证类型;
}
}
}
}
您可以使用带有
group=true
参数的reduce函数,即

<couchdb>/<database>/_design/ddoc/_view/partners?group=true
然而,这是相当不鼓励的,因为您正在reduce函数中构建数据结构。Reduce函数应该返回简单的、通常是数字的值。此外,上述reduce函数在reduce情况下可能会中断。我还没有测试过这个。作为替代方案,我可以建议仅使用map函数实现查询,即

<couchdb>/<database>/_design/ddoc/_view/partners?reduce=false&key="Partner1"

我使用以下方法使其工作:

function(keys, values, rereduce){
  var item = {};
  r=[];

  values.forEach(function(value){
    item[value] = value;
  });

  for(var i in item){
    r.push(item[i]);
  }

  return r; 
}
如果这是不正确的,欢迎评论,但它会以所需的形式将数据返回给我:

PartnerName: VoucherType[]

您的目标不是减少数据量,而是更改格式。 因此,不要使用reduce函数,而要使用reduce函数

功能(头部,需求){
var lastKey,行,重复数据消除;
while(row=getRow()){
if(row.key!==lastKey){
重复数据={};
发送('\n'+row.key+':');
}
如果(!重复数据消除[row.value]){
if(row.key==lastKey){
发送(',');
}
重复数据消除[行值]=真;
发送(行值);
}
lastKey=row.key;
}
}
这只是一个纯文本列表,但您可以添加所需的任何格式,例如JSON

Partner1: Voucher Type 1, Voucher Type 2
Partner2: Voucher Type 1

如果您不需要重复数据消除,那么它就更简单。

问题是,可能有一百万个文档,因此它将输出一百万行。我试图得到(基本上)名称:VoucherType[](就像第一个想法,group=true)在第一个选项中,我得到了“减少产出必须更快地收缩”啊,我担心这会发生。基本上,这告诉你我在回答中展示的reduce函数是个坏主意。您可以将配置中的字段
reduce\u limit
更改为
false
,但我认为您最好不要这样做。另请参见:在这种情况下,您绝对不应该这样做,因为数据的大小根本没有减少。运行map reduce将非常低效。参数
value
在函数签名中出现两次,这可能不是预期的。我不清楚您是否希望具有唯一的值,这可能是您希望通过将
数组转换为
对象来实现的。不管怎样,我想你必须分别考虑ReReExcel情况,因为你将在“代码>项目< <代码>对象Objiste中使用数组密钥。更改<代码> r= r.Press(item [i]);<代码>对于
r=r.concat(i)如果希望更好地可视化数据
PartnerName: VoucherType[]
Partner1: Voucher Type 1, Voucher Type 2
Partner2: Voucher Type 1