0

I'm new to Couchbase and am struggling to get a composite index to do what I want it to. The use-case is this:

  • I have a set of "Enumerations" being stored as documents
  • Each has a "last_updated" field which -- as you may have guessed -- stores the last time that the field was updated
  • I want to be able to show only those enumerations which have been updated since some given date but still sort the list by the name of the enumeration

I've created a Couchbase View like this:

function (doc, meta) {
   var time_array;
   if (doc.doc_type === "enum") {
      if (doc.last_updated) {
         time_array = doc.last_updated.split(/[- :]/);
      } else {
         time_array = [0,0,0,0,0,0];
   }
   for(var i=0; i<time_array.length; i++) { time_array[i] = parseInt(time_array[i], 10); }
   time_array.unshift(meta.id);
   emit(time_array, null);
}

}

I have one record that doesn't have the last_updated field set and therefore has it's time fields are all set to zero. I thought as a first test I could filter out that result and I put in the following:

startkey = ["a",2012,0,0,0,0,0]
endkey = ["Z",2014,0,0,0,0,0]

While the list is sorted by the 'id' it isn't filtering anything! Can anyone tell me what I'm doing wrong? Is there a better composite view to achieve these results?

Rajdeep Singh
  • 17,621
  • 6
  • 53
  • 78
ken
  • 8,763
  • 11
  • 72
  • 133

1 Answers1

1

In couchbase when you query view by startkey - endkey you're unable to filter results by 2 or more properties. Couchbase has only one index, so it will filter your results only by first param. So your query will be identical to query with:

startkey = ["a"]
endkey = ["Z"]

Here is a link to complete answer by Filipe Manana why it can't be filtered by those dates.

Here is a quote from it:

For composite keys (arrays), elements are compared from left to right and comparison finishes as soon as a element is different from the corresponding element in the other key (same as what happens when comparing strings à la memcmp() or strcmp()).

So if you want to have a view that filters by date, date array should go first in composite key.

m03geek
  • 2,508
  • 1
  • 21
  • 41
  • What I don't understand, though, is that if I don't bring in the string component and instead just use the array elements that are the various aspects of the date and time, I can filter using start/end_key through to any element of the array and it appears they're being used for sorting purposes too. – ken Jun 14 '13 at 14:22
  • Yes. Couchbase sorts result by key, so if you have complex key like `[doc.a, doc.b, doc.c]` docs will be sorted by doc.a first, then values with same doc.a will be sorted by doc.b and so on. The same behavior is used for filtering if `startkey: ['a','b','c']` and `endkey: ['z','x','c']` couchbase find all keys that staisfy only first condition. But if you have same values in start/end keys like `['a','b']` and `['a','x']` couchbase will select docs with `doc.a = 'a' `and `doc.b = 'b'..'x'`. – m03geek Jun 14 '13 at 21:41