Search code examples
c#.netcouchbasecouchbase-view

Get counter documents from couchbase view


We using Couchbase's increment function to store some counters on variable keys with constant prefix SomePrefix_. We define view that get all documents which keys start with SomePrefix_:

function (doc, meta) {
  if (meta.id.indexOf("SomePrefix_") === 0) {
    emit(meta.id, doc);
  }
}

When we query the view we get values like "Mg==", "MQ==" etc. .NET SDK fails to load view results and map it to integers.

Any workarounds?


Solution

  • First of all a view might not be the best approach here depending on what the objective is. If all the keys are known then it will be quicker to use a CRUD operation and not a view. If the requirements are to use a reduce to find the average or max of all the keys, or the keys are simple not known then a view is the correct way to go about it.

    Internal to Couchbase Server counters are store as binary and not JSON. As a result the view engine converts binary into base64. When the doc is decode (decodeBase64(doc)) it will be to a ASCII code. Which needs to be then convert to a string using String.fromCharCode(decode[i]) This needs to be done for each digit in turn.

    For example if the counter doc is Mg==, when it is decoded it will have the ASCII code 50 which is the decimal string 2.

    This view should do the trick.

    function (doc, meta) {
      if (meta.id.indexOf("counter_") === 0) {
        var decode = decodeBase64(doc);
        var value = null;
        for (i = 0; i < decode.length; ++i) {
          if (value == null) {
            value = String.fromCharCode(decode[i]);
          } else {
            value += String.fromCharCode(decode[i]);
          }
        }
        emit(meta.id, parseInt(value));
      }
    }