7

如果我的收藏看起来像这样,我如何获得收藏中的总评论数。(不是每个帖子的总评论数,而是集合的总评论数。)

{
    _id: 1,
    post: 'content',
    comments: [
        {
            name: '',
            comment: ''
        }
    ]
}

如果我有 3 条评论的帖子 A 和 5 条评论的帖子 B。结果应该是 8。

4

2 回答 2

15

You could use the aggregation framework:

> db.prabir.aggregate(
    { $unwind : "$comments" },
    { $group: {
        _id: '',
        count: { $sum: 1 }
    }
})
{ "result" : [ { "_id" : "", "count" : 8 } ], "ok" : 1 }

In a nutshell this (temporarily) creates a separate document for each comment and then increments count for each document.


For a large number of posts and comments it might be more efficient to keep track of the number of comments. When ever a comment is added you also increment a counter. Example:

// Insert a comment
> comment = { name: 'JohnDoe', comment: 'FooBar' }
> db.prabir.update(
    { post: "A" },
    {
        $push: { comments: comment },
        $inc: { numComments: 1 }
    }
)

Using the aggregation framework again:

> db.prabir.aggregate(
    { $project : { _id: 0, numComments: 1 }},
    { $group: {
        _id: '',
        count: { $sum: "$numComments" }
    }
})
{ "result" : [ { "_id" : "", "count" : 8 } ], "ok" : 1 }
于 2013-02-03T03:15:19.430 回答
9

You can use the aggregate method of the aggregation framework for that:

db.test.aggregate(
  // Only include docs with at least one comment.
  {$match: {'comments.0': {$exists: true}}},
  // Duplicate the documents, 1 per comments array entry
  {$unwind: '$comments'},
  // Group all docs together and count the number of unwound docs,
  // which will be the same as the number of comments.
  {$group: {_id: null, count: {$sum: 1}}}
);

UPDATE

As of MongoDB 2.6, there's a more efficient way to do this by using the $size aggregation operator to directly get the number of comments in each doc:

db.test.aggregate(
  {$group: {_id: null, count: {$sum: {$size: '$comments'}}}}
);
于 2013-02-03T03:13:21.250 回答