Get the total number of subdocuments in the collection

How to get general comments in a collection if my collection looks like this. (not the total number of comments per post, but the total number for the collection.)

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

If I have a post A with 3 comments and a post B with 5 comments. The result should be 8.

+5
source share
2 answers

You can use the aggregation structure :

> 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 enlarges countfor each document.


For a large number of posts and comments, it would be more efficient to track the number of comments. When a comment is added, you also increment the counter. Example:
// Insert a comment
> comment = { name: 'JohnDoe', comment: 'FooBar' }
> db.prabir.update(
    { post: "A" },
    {
        $push: { comments: comment },
        $inc: { numComments: 1 }
    }
)

:

> db.prabir.aggregate(
    { $project : { _id: 0, numComments: 1 }},
    { $group: {
        _id: '',
        count: { $sum: "$numComments" }
    }
})
{ "result" : [ { "_id" : "", "count" : 8 } ], "ok" : 1 }
+12

aggregate :

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

MongoDB 2.6, , $size, :

db.test.aggregate(
  {$group: {_id: null, count: {$sum: {$size: '$comments'}}}}
);
+8

All Articles