Điều quan trọng là phải hiểu rằng các thao tác trong đối số để tổng hợp () tạo thành một đường dẫn . Điều này có nghĩa là đầu vào cho bất kỳ phần tử nào của đường dẫn là dòng tài liệu được tạo bởi phần tử trước đó trong đường ống.
Trong ví dụ của bạn, truy vấn đầu tiên của bạn tạo một đường dẫn tài liệu giống như sau:
{
"_id" : 2,
"avg_score" : 5.5
},
{
"_id" : 1,
"avg_score" : 4
}
Điều này có nghĩa là phần tử thứ hai của đường ống dẫn đang xem một loạt tài liệu trong đó các khóa duy nhất là "_id" và "avg_score". Các khóa "category_id" và "score" không còn tồn tại trong luồng tài liệu này.
Nếu bạn muốn tổng hợp thêm trên luồng này, bạn sẽ phải tổng hợp bằng cách sử dụng các khóa được nhìn thấy ở giai đoạn này trong đường dẫn. Vì bạn muốn tính giá trị trung bình, bạn cần phải đặt một giá trị hằng số duy nhất cho trường _id, để tất cả các tài liệu đầu vào được nhóm lại thành một kết quả duy nhất.
Đoạn mã sau tạo ra kết quả chính xác:
db.questions.aggregate(
{ $group : {
_id : "$category_id",
avg_score : { $avg : "$score" },
}
},
{ $group : {
_id : "all",
avg_score : { $avg : "$avg_score" },
}
}
);
Khi chạy, nó tạo ra kết quả sau:
{
"result" : [
{
"_id" : "all",
"avg_score" : 4.75
}
],
"ok" : 1
}