Search code examples
couchbasecouchbase-view

Couchbase reduce multiple values


I am building a view in Couchbase 3.0.1 and would like to reduce multiple values from a map, but I am not sure the right approach.

In the case of an order object, the problem I am trying to solve is that I would like to reduce multiple values from the map (specifically, subtotal, tax and total). I began by outputting the values as an object:

function (doc, meta) {
  if (doc.object == "order") {
    emit(dateToArray(doc.order_date), {subtotal: doc.subtotal, tax: doc.tax, total: doc.total});
  }
}

However, this has not helped me much because I am not sure how to go about reducing the values when the map outputs a custom object. Obviously the built in _sum reduce function won't handle it, so:

Can someone offer some advice on the best way to reduce several values from a map output in Couchbase?


Solution

  • You can write your own custom reduce function. The custom reduce accepts 3 parameters:

    1. key - one of the keys emitted by map
    2. values - an array of values emitted for that particular key
    3. rereduce - whether this is a first call to reduce, or a re-reduce which aggregates intermediate values returned by the reduce itself.

    In your case, you just want a simple sum so the code for the reduce is the same as the rereduce: calculating the sum of the 3 order object properties and returning the result. It should look something like this (typing from memory, JS syntax might be slightly off.)

    reduce(key, values, rereduce) {
      var result = values[0];
    
      for(var i = 1; i < values.length; i++) {
        result.subtotal += values[i].subtotal;
        result.tax += values[i].tax;
        result.total += values[i].total;
      }
    
      return result;
    }