node.jsviewcouchdbcradle

emit doc twice with different key in couchdb


Say I have a doc to save with couchDB and the doc looks like this:

{
   "email": "lorem@gmail.com",
   "name": "lorem",
   "id": "lorem",
   "password": "sha1$bc5c595c$1$d0e9fa434048a5ae1dfd23ea470ef2bb83628ed6"
}

and I want to be able to query the doc either by 'id' or 'email'. So when save this as a view I write so:

db.save('_design/users', {
    byId: {
        map: function(doc) {
            if (doc.id && doc.email) {
                emit(doc.id, doc);
                emit(doc.email, doc);
            }
        }
    }
});

And then I could query like this:

db.view('users/byId', {
    key: key
}, function(err, data) {
    if (err || data.length === 0) return def.reject(new Error('not found'));
    data = data[0] || {};
    data = data.value || {};

    self.attrs = _.clone(data);
    delete self.attrs._rev;
    delete self.attrs._id;

    def.resolve(data);
});

And it works just fine. I could load the data either by id or email. But I'm not sure if I should do so.

I have another solution which by saving the same doc with two different view like byId and byEmail, but in this way I save the same doc twice and obviously it will cost space of the database.

Not sure which solution is better.


Solution

  • The canonical solution would be to have two views, one by email and one by id. To not waste space for the document, you can just emit null as the value and then use the include_docs=true query paramter when you query the view.

    Also, you might want to use _id instead of id. That way, CouchDB ensures that the ID will be unique and you don't have to use a view to loop up documents.