如何将注释计数填充到项目列表?

时间:2013-04-29 01:30:32

标签: node.js mongodb express mongoose

我的应用中有两个模型:项目和评论。一个Item可以有很多注释,一个Comment实例包含一个带有键'comment'的Item实例的引用,以跟踪关系。

现在,当用户请求特定URL时,我必须发送所有项目的JSON列表及其注释计数。

function(req, res){
  return Item.find()
    .exec(function(err, items) {
        return res.send(items);
    });
};

我不确定如何“填充”对项目的评论计数。这似乎是一个普遍的问题,我倾向于认为应该有比蛮力更好的方式来做这项工作。

所以请分享你的想法。您如何将评论计数“填充”到项目?

2 个答案:

答案 0 :(得分:0)

检查MongoDB文档并查找方法findAndModify() - 使用它可以自动更新文档,例如添加注释并同时增加文档计数器。

<强> findAndModify

findAndModify命令以原子方式修改并返回单个文档。默认情况下,返回的文档不包括对更新所做的修改。要返回包含对更新所做修改的文档,请使用新选项。

示例

使用update选项,将更新运算符$inc用于计数器,使用$addToSet将实际注释添加到嵌入的注释数组中。

 db.runCommand(
            {
              findAndModify: "item",
              query: { name: "MyItem", state: "active", rating: { $gt: 10 } },
              sort: { rating: 1 },
              update: { $inc: { commentCount: 1 }, 
                        $addToSet: {comments: new_comment}  }
            }
              )

见:

MongoDB: findAndModify

MongoDB: Update Operators

答案 1 :(得分:0)

我对这个问题进行了一些研究,得出了以下结果。首先,MongoDB文档suggest

  

通常,在以下情况下使用嵌入式数据模型:

     
      
  • 您在实体之间拥有“包含”关系。
  •   
  • 您有一对多的关系,其中“很多”对象始终显示或在其父文档的上下文中查看。
  •   

所以在我的情况下,如果将Comment嵌入到Item中,而不是独立存在,那就更有意义了。

尽管如此,我很想知道解决方案而不改变我的数据模型。作为MongoDB文档中的mentioned

  

引用提供比嵌入更多的灵活性;但是,到   解析引用,客户端应用程序必须发布后续行动   查询。换句话说,使用引用需要更多的往返   服务器。

由于多次往返是犹太人,我想出了以下解决方案:

var showList = function(req, res){

  // first DB roundtrip: fetch all items
  return Item.find()
        .exec(function(err, items) {
            // second DB roundtrip: fetch comment counts grouped by item ids
            Comment.aggregate({
                $group: {
                    _id: '$item',
                    count: {
                        $sum: 1
                    }
                }
            }, function(err, agg){
                // iterate over comment count groups (yes, that little dash is underscore.js)
                _.each(agg, function( itr ){
                    // for each aggregated group, search for corresponding item and put commentCount in it
                    var item = _.find(items, function( item ){
                        return item._id.toString() == itr._id.toString();
                    });
                    if ( item ) {
                        item.set('commentCount', itr.count);
                    }
                });
                // send items to the client in JSON format
                return res.send(items);
            })          
        });

};

同意?不同意?请赐教你的意见!

如果你有更好的答案,请在这里发帖,如果我觉得它值得,我会接受的。