3

我在我的沙发数据库上有一个视图,它以这种格式输出数据:

{"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"]

目前,我的 map reduce 函数如下所示:

地图:

function(
    emit([doc.PartnerName, doc.VoucherType], 1);
}

减少:

function(keys, values) {
    return true;
}

我正在查询group=true

我怀疑我需要在 reduce 函数中做更多的事情?

4

3 回答 3

2

您的目标不是减少数据量,而是改变格式。所以不要使用reduce函数,使用list函数

function(head, req) {
    var lastKey, row, dedup;

    while (row = getRow()) {
        if (row.key !== lastKey) {
            dedup = {};
            send('\n' + row.key + ': ');
        }

        if (!dedup[row.value]) {
            if (row.key === lastKey) {
                send(', ');
            }

            dedup[row.value] = true;
            send(row.value);
        }

        lastKey = row.key;
    }
}

这只是给你一个纯文本列表,但你可以添加任何你想要的格式,例如 JSON。

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

如果您不需要重复数据删除,那就更简单了。

于 2014-01-07T14:03:25.600 回答
1

考虑以下设计文档:

{
   "_id": "_design/ddoc",
   "views": {
       "partners": {
           "map": function(doc) {
                      emit(doc.PartnerName, doc.VoucherType);
                  },
           "reduce": function(keys, values) {
                         var voucherTypes = [];
                         values.forEach(function(v) {
                             voucherTypes = voucherTypes.concat(v);
                         });
                         return voucherTypes;
                     }
       }
   }
}

您可以做的是使用带有group=true参数的reduce函数,即

<couchdb>/<database>/_design/ddoc/_view/partners?group=true

这会给你这样的东西:

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

然而,这是相当不鼓励的,因为您在 reduce 函数中构建数据结构。Reduce 函数应该返回简单的,通常是数值。此外,上述 reduce 函数可能会在 rereduce 情况下中断。我没有测试过这个。作为替代方案,我可以建议仅使用地图功能实现查询,即

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

这将返回:

{"total_rows":4,"offset":0,"rows":[
{"id":"97c7ee4d90f57407bb1f4f680d20967b","key":"Partner1","value":"Voucher Type 1"},
{"id":"97c7ee4d90f57407bb1f4f680d20a049","key":"Partner1","value":"Voucher Type 2"}
]}
于 2013-04-30T13:34:08.513 回答
1

我通过使用以下减少使其工作:

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[]
于 2013-04-30T14:54:11.050 回答