1

On couchDB I have the following view:

function(doc) {
  if(doc._id === 'countryMobileNumberCodes') {
    Object.keys(doc.dictionary).forEach(function(k, i) {
      emit(k, doc.dictionary[k]);
    });
  }
}

This emits the following result:

{"total_rows":2,"offset":0,"rows":[
{"id":"countryMobileNumberCodes","key":"1","value":"+265"},
{"id":"countryMobileNumberCodes","key":"2","value":"+27"}
]}

This same view on Android (using couchbase-lite-android 1.2.1) does not emit any rows. However, if I were to change the view to this:

function(doc) {
  if(doc._id === 'countryMobileNumberCodes') {
    emit(doc._id, doc.dictionary);
  }
}

Then I do get results from couchbase-lite (so the docs definitely exist on the mobile device).

Does CouchDB implement MapReduce differently to couchbase-lite?

I have seen reference to the fact that couchbase-lite and CouchDB are 100% compatible, but that does not seem to be the case (Couchbase-lite and CouchDB).

Zach Smith
  • 8,458
  • 13
  • 59
  • 133
  • They are compatible in that they can sync with each other, but other than that they are two products developed by two entities. They use different Javascript engines, etc. – borrrden May 24 '16 at 21:12

1 Answers1

0

Presumably you are using Couchbase Lite's REST API, probably within PhoneGap or Cordova. It looks as though the JavaScript interpreter in that container doesn't support Object.keys or foreach(). You'll probably need to rewrite your map and reduce functions using only older features of JavaScript.

(My JS is very rusty so I can't tell you what version of the language added those APIs. It's also possible they're not built-in but are part of a library that CouchDB includes in its JS context as a convenience.)

Jens Alfke
  • 1,946
  • 12
  • 15
  • Thanks for the answer. A for (var key in obj) loop also didn't work – Zach Smith Jun 07 '16 at 06:29
  • Well, all I can say is that the map/reduce implementation is the same as CouchDB, so whatever you're running into is something that has to do with JS programming, that's preventing the `emit` function from being called. You'll need to find a way to debug the contents of the map function so you can see what it's doing wrong. Maybe copy the code somewhere else in your app where you can debug it more easily? – Jens Alfke Jun 08 '16 at 15:40
  • Couchbase-lite is running on Android. There is a result from the view, the rows arrays is empty. Is it still possible that emit is not being called? – Zach Smith Jun 08 '16 at 15:41
  • 1
    If there aren't any rows in the query result, and you're not constraining the query with a startkey/endkey/keys param, then `emit` isn't being called, yes. Every call to `emit` adds a row to the view index. – Jens Alfke Jun 09 '16 at 16:46
  • Thanks. I had never considered that no results in the rows array means that the emit() function is never called. Seems obvious in hindsight. However I still can't see a reason that `for (var k in doc.obj) {if doc.obj.hasOwnProperty(k) {...}}` wouldn't work. the code works on CouchDB. And the documents definitely exist in Couchbase-lite. – Zach Smith Jun 10 '16 at 07:27
  • I'm actually looping over a sub object of the doc object. Would this have any effect on Couchbase-lite? – Zach Smith Jun 10 '16 at 07:28
  • Most likely your map function is throwing an exception at some point, which aborts it. It's a pretty common error to try to use a nonexistent property value, for example. Can you check the app's logs or console output to see if there are error messages being printed? I don't know the Android CBL implementation well, but I would hope that it logs an error message when this happens. You can also try calling `log("...")` from the map function; this _should_ write a log message. Then you can do some printf-type debugging. – Jens Alfke Jun 11 '16 at 20:41