CouchDB view – reduce / group duplicate key values to array

couchdbmapreduce

I've got a view on my couch db, which outputs data in this format:

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

What I'm trying to get do is effectively 'group' the Partner | Voucher Type,
So in the example above, It would return be something like:

Partner1: ["Voucher Type 1", "Voucher Type 2"]
Partner2: ["Voucher Type 1"]
Partner3: ["Voucher Type 1"]
Partner4: ["Voucher Type 1"]

Currently, my map reduce functions look like this:

Map:

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

Reduce:

function(keys, values) {
    return true;
}

I'm querying with group=true

I suspect I need to do more in the reduce function?

Best Solution

Your aim is not to reduce the amount of data, only to change the format. So do not use a reduce function, use a list function.

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;
    }
}

This one just gives you a plaintext listing, but you can add whatever formatting you desire, e.g. JSON.

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

If you don't need the de-duplication, then it's even simpler.

Related Question