2013-02-03 37 views
5

Làm cách nào để nhận được tổng số nhận xét trong bộ sưu tập nếu bộ sưu tập của tôi trông như thế này. (không phải tổng số nhận xét cho mỗi bài đăng nhưng tổng số cho bộ sưu tập.)nhận tổng số tài liệu phụ trong bộ sưu tập

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

Nếu tôi có bài đăng A với 3 nhận xét và bài B với 5 nhận xét. Kết quả sẽ được 8.

Trả lời

12

Bạn có thể sử dụng aggregation framework:

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

Tóm lại này (tạm thời) tạo ra một tài liệu riêng biệt cho mỗi bình luận và sau đó tăng count cho mỗi tài liệu.


Đối với số lượng lớn bài đăng và nhận xét, có thể sẽ hiệu quả hơn để theo dõi số lượng nhận xét. Khi một bình luận được thêm vào, bạn cũng tăng một bộ đếm. Ví dụ:

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

Sử dụng khuôn khổ hợp một lần nữa:

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

Tôi mới đến MongoDB. Mã đó để có được một số đơn giản ... thật khủng khiếp. – otocan

8

Bạn có thể sử dụng phương pháp aggregate của aggregation framework cho rằng:

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

CẬP NHẬT

Tính đến MongoDB 2.6, có một cách hiệu quả hơn để làm điều này bằng cách sử dụng toán tử tổng hợp $size để trực tiếp nhận được số lượng nhận xét trong mỗi tài liệu:

db.test.aggregate(
    {$group: {_id: null, count: {$sum: {$size: '$comments'}}}} 
); 
Các vấn đề liên quan