CouchDB从Node.js中获取用户的所有帖子

时间:2012-07-29 04:00:13

标签: javascript node.js database-design couchdb couchdb-nano

我首先要说我做了很多研究,但我还是迷失了。

我有一个正常工作的版本,但这是你能做到的最低效的方式我敢肯定。我对确定计划数据库的最佳方式并不十分自信,显然我已经变得依赖于ActiveRecord。无论如何,我只想弄清楚这些事情:

  1. 找出规划数据库的最佳方式(我应该如何分开文档)
  2. 找到最有效的处理关系
  3. 找到从服务器查询的好方法
  4. 好的,我注意到了一些事情:一,你不能将我的客户端变量传递给视图,所以使用这样的方法是行不通的。第二,我认为可能会有所有帖子,然后检查类型是否发布然后返回匹配的文档,但这似乎有很多数据在移动。

    一些代码:

    所以我使用Node.js,CouchDB和nano作为中间件。

    发布文件:

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

    用户文档:

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

    这就是我目前如何获取所有帖子(这真的很糟糕!):

    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);
        });
    });
    

    我一直在使用视图,直到我意识到我无法传递一个变量,然后我查看了列表但是在阅读了很多教程后我迷失了。

    感谢您的帮助!!

2 个答案:

答案 0 :(得分:2)

你真的想要使用一个视图。只需在用户作为关键字的帖子上创建视图。

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

然后你可以简单地查询它:

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

这将为您提供与该用户关联的所有视图文档。

答案 1 :(得分:0)

像Will Hartung所说的那样,你想要一个观点,但它看起来应该与Will表现出的有点不同。

首先确保您要发射的字段存在。请注意,null0是JavaScript中的虚假值,因此根据您的数据结构,您可能必须明确检查字段是否为undefined

以下是一些代码,向您展示我的意思。

function(doc) {
    if (doc.user && doc.title) { // This check is important
        emit(doc.user, {title: doc.title, date: doc.date});
    }
}

您无需显式发出文档ID,因为无论如何都会自动发生。另外,请确保不要发出整个文档emit(doc.user, doc);。这是低效的。如果您需要整个文档,只需将null作为值发出,并使用include_docs=true网址参数。

所以基本上如果你将null作为一个值发出,那么你就会得到这样的文档。

  

GET / yourdb / _design / app / _view / by_user?key = film42&amp; include_docs = true