Query View Searching string value with like codition

40-beta

#1

I write a view in Couchbase server:

function (doc, meta) {
  if(doc.type && doc.status != -1) {
    emit(doc.name, null);
  }
}

Then i want to search docs that doc.name like '%jan%'.
So i do:

var kw = 'jan';
var q = ViewQuery.from('poliact', 'get_by_name')
      .range( kw , kw + JSON.parse('"\u0FFF"'))
      .stale(ViewQuery.Update.BEFORE)
      .limit(10);

But this only match: doc.name like 'jan%';
So i change:

    var kw = 'jan';
    var q = ViewQuery.from('poliact', 'get_by_name')
          .range( kw + JSON.parse('"\u0000"'), kw + JSON.parse('"\u0FFF"'))
          .stale(ViewQuery.Update.BEFORE)
          .limit(10);

or:

var kw = 'jan';
var q = ViewQuery.from('poliact', 'get_by_name')
              .range( JSON.parse('"\u0000"') + kw , kw + JSON.parse('"\u0FFF"'))
              .stale(ViewQuery.Update.BEFORE)
              .limit(10);

But error:

SyntaxError: Unexpected token

How can solve my problem?


#2

Hey Sonrobby,

There are two issues with the way you are going about this, the first is primarily that the view engine does an in-order comparison of the characters in the string, this is what allows you to use \uFFFF at the end of the string to match any postfix, however this trick will not work for prefixes. Additionally you are using a null-byte (\u0000) which is an error and would not be parseable. The only way I am aware of to accomplish what you are attempting is to emit multiple strings for each real map-reduce item. This will however incur quite a significant indexing performance penalty.

Example:

function (doc, meta) {
  if(doc.type && doc.status != -1) {
    for (var i = 1; i < doc.name.length - 1; ++i) {
      emit('%' + doc.name.substr(i), null);
    }
    emit(doc.name, null);
  }
}
.range('%' + kw, '%' + kw + JSON.parse('"\u0FFF"'))

Cheers, Brett


#3

Thanks @brett19. But size of this view will be larger?
And another, i want to get total_rows from View result in Nodejs SDK. In the bucket.query(q, function(err, values) {}); the values not contain this attribute.


#4

Hey Sonrobby,

The size of the view would indeed be significantly larger, but I am otherwise not aware of allowing a wildcard postfix search. Additionally, total_rows is part of the meta-data for the query, available as the third callback parameter:

.query(..., function(err, rows, meta) {
  console.log(meta.total_rows);
});

Cheers, Brett