javascriptnode.jsdatabase-designcouchdbcouchdb-nano

CouchDB getting all posts from user in Node.js


I'll start off by saying I've done a lot of research but I'm still pretty lost.

I have a working version, but it's the most inefficient way you can do this I'm sure. I'm not super confident about knowing the best way to plan out a DB, I've become to dependent on ActiveRecord, clearly. Anyways, I'm simply trying to figure out these things:

  1. Find out the best way to plan the db (how I should separate documents)
  2. Find the most efficient to deal with relations
  3. Find good method to query from the server

Ok, so some things I've noticed: One, you can't pass I client variable into views so using a method like that won't work. Two, I think there might be away to get all posts and then check if the type is post and then return the matching documents, but that seems like a lot of data moving around.

Some code:

So I'm using Node.js, CouchDB, and nano as middleware.

Post Document:

{
"_id": "post-slug",
"title": "Post Slug",
"user": "film42",
"date": 1343451412,
"type": "post"
}

User Document:

{
"_id": "film42",
"email": "test@example.com",
"posts": [
   "post-slug",
   "another-post-slug"
],
"type": "user"
}

And here's how I currently fetch all posts (It's really bad!):

function buildUserPostArray(array, user, res, i) {
   db.get(user.posts[i], function(err, post_obj) {
       if(i < user.posts.length) {
           array.push(post_obj);
           buildUserPostArray(array, user, res, i+1);
       }
       else {
           console.log('Rendering view now.');
           res.render('user.jade', {
               user: user.user,
               posts: array
           });
       }
   });
}

app.get('/users/:id', function(req, res) {
    db.get(req.params.id, function(err, user_obj) {
       if(err) res.send('err1'); //bad id or server down

       array = [];
       buildUserPostArray(array, user_obj, res, 0);
    });
});

I was using views until I realized that I can't pass a variable and then I looked into lists but I got lost after reading many tutorials.

Thanks for the help!!


Solution

  • You really want to use a view. Simply create the view on the post with the user as the key.

    function(doc) {
        emit(doc.user, {title: doc.title, date: doc.date, id: doc._id});
    }
    

    Then you can simply query it:

    GET /yourdb/_design/app/_view/by_user?key=film42
    

    That will give you all of the view documents associated with that user.