user1477388
user1477388

Reputation: 21440

CouchDB Emit with no parameters

Consider the following code:

module.exports = {
  by_author: {
    map: function(doc) {
      if ('authors' in doc) {
        doc.authors.forEach(emit);
      }
    }.toString(),
    reduce: '_count'
  },

  by_subject: {
    map: function(doc) {
      if ('subjects' in doc) {
        doc.subjects.forEach(function(subject){
          emit(subject, subject);

          subject.split(/\s+--\s+/).forEach(function(part){
            emit(part, subject);
          });
        });
      }
    }.toString(),

    reduce: '_count'
  }
};

It doesn't look like doc.authors.forEach(emit); is valid syntax (or good coding) but it appears to be syntactically correct.

My question is, is this shorthand for the following:

doc.authors.forEach(function(_doc) {
    emit(_doc.id, _doc);
});

If so, is there any benefit to using this shorthand? How does it work?

Ref. https://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Map_Functions

Upvotes: 1

Views: 159

Answers (1)

Dominic Barnes
Dominic Barnes

Reputation: 28439

emit is a function that CouchDB exposes. In JS functions are first-class. (and can be passed as arguments to other functions)

In lieu of explaining all of that, I'll just show you what your code is actually doing. (read up more about functions in JS if you're new)

doc.authors.forEach(emit);

doc.authors.forEach(function (item, index, list) {
  emit(author, index, list);
});

In JS, the arguments passed to the forEach handler fn are:

  • the item in the array (ie: "some user")
  • the index of that item in the array (eg: 0)
  • the entire array (eg: [ "some user" ])

The emit() function only accepts 2 arguments, so the 3rd will simply be ignored. Thus, in the case of a single item array, you will get the equivalent of emit("some user", 0). If there are multiple items, you'll get other emits as well.

Upvotes: 3

Related Questions