2012-09-16 33 views
27

Tôi có một cơ sở dữ liệu về sinh viên và các chi tiết liên lạc của họ. Tôi đang cố gắng tìm ra mã bưu điện chứa nhiều sinh viên nhất. Các tài liệu cho học sinh giống như thế này ...tập hợp mongodb

{studentcode: 'smi0001', firstname: 'bob', họ: 'smith', mã bưu điện: 2001}

tôi nghĩ tôi có thể sử dụng khuôn khổ hợp để tìm ra mã bưu điện với hầu hết các sinh viên bằng cách làm một cái gì đó giống như ...

db.students.aggregate({$project: { postcode: 1 }, $group: {_id: '$postcode', students: {$sum: 1}}}) 

này làm việc như mong đợi (trả postcodes như _id và số lượng sinh viên trong mỗi mã bưu điện là 'sinh viên', nhưng nếu tôi thêm $sort vào đường ống, có vẻ như cố gắng sắp xếp theo toàn bộ tuyển tập sinh viên thay vì kết quả của hoạt động $group.

những gì tôi đang cố gắng nhìn như ...

db.students.aggregate({$project: { postcode: 1 }, $group: {_id: '$postcode', students: {$sum: 1}}, $sort: {_id: -1}}) 

nhưng nó trả lại toàn bộ bộ sưu tập và không quan tâm đến những điều gì đó $project$group ... Tôi có thiếu? Tôi nghĩ rằng tôi chỉ có thể sắp xếp theo số lượng học sinh giảm dần và trả lại mục đầu tiên. Cảm ơn bạn trước vì đã giúp đỡ.

Trả lời

47

Bạn gần như đã có nó ...

db.test.aggregate(
    {$group: {_id: '$postcode', students: {$sum: 1}}}, 
    {$sort: {_id: -1}} 
); 

cho (tôi đã thêm một số dữ liệu thử nghiệm phù hợp với mẫu của bạn):

{ 
    "result" : [ 
    { 
     "_id" : 2003, 
     "students" : 3 
    }, 
    { 
     "_id" : 2002, 
     "students" : 1 
    }, 
    { 
     "_id" : 2001, 
     "students" : 2 
    } 
    ], 
    "ok" : 1 
} 

Bạn có một bên ngoài {} xung quanh tất cả mọi thứ, nhưng lại gây một số nhầm lẫn . Nhóm và sắp xếp không hoạt động như các hoạt động riêng biệt trong đường ống.

Bạn không thực sự cần dự án cho trường hợp này.

Cập nhật Có thể bạn muốn sắp xếp theo "sinh viên", như vậy, để có được những zipcodes lớn nhất (theo dân số) đầu tiên:

db.test.aggregate(
    {$group: {_id: '$postcode', students: {$sum: 1}}}, 
    {$sort: {students: -1}} 
); 
+0

Cảm ơn đống lời khuyên. Tôi không thể tin rằng nó chỉ là một vấn đề khung không đúng chỗ. Đây là những vấn đề tôi từng học SQL 15 năm trước, việc chuyển sang Mongodb có nghĩa là bỏ lại rất nhiều kiến ​​thức trước đây, nhưng tôi cho rằng nó sẽ đáng giá. Chúc mừng, –

+0

Tính năng này phù hợp với trường hợp sử dụng của bạn, nhưng cách tiếp cận này không phải lúc nào cũng đảm bảo kết quả bạn mong đợi. Ví dụ kết quả sẽ không chính xác khi bạn cần nhóm theo 'field1' nhưng giữ nó được sắp xếp theo' field2'. – astronaut

+0

Tôi có mã bưu điện POST1, POST2, POST3, mỗi mã bưu điện không giống như số lượng sinh viên. Truy vấn sắp xếp của tôi sẽ là gì để nhận tổng của mỗi POST. db.test.aggregate ( {$ group: {_id: {'postcodes': '$ postcodes'}, sinh viên: {$ sum: 1}}}, Truy vấn sắp xếp ở đây là gì. ); –

3

Tôi nghĩ rằng cú pháp của bạn là hơi sai. Mỗi phép toán gộp trong đường dẫn phải là tài liệu riêng của nó.

db.students.aggregate({$project: ...}, {$group: ...}, {$sort: ...}) 

Trong trường hợp của bạn, nó phải là:

db.students.aggregate(
    {$project: { postcode: 1 }}, 
    {$group: {_id: '$postcode', students: {$sum: 1}}}, 
    {$sort: {students: -1}} 
) 

Tôi đã thử nghiệm nó trên một bộ sưu tập mẫu dựa trên giản đồ của bạn và nó làm việc cho tôi, phân loại các mã bưu nhóm lại theo số lượng sinh viên , giảm dần.

+0

'$ project' có làm gì cho bạn trong trường hợp này không? –

+0

@WesFreeman Bạn nói đúng, dự án $ có thể bị bỏ qua. Tôi đoán nếu bạn có tài liệu thực sự lớn, cắt tỉa chúng xuống chỉ những thông tin cần thiết để tiếp tục xử lý trong đường ống có thể là lợi thế, nhưng trong trường hợp này, không có nhiều là đạt được. – Thomas

+0

vâng, tài liệu 'sinh viên' của tôi thực sự có nhiều trường hơn, vì vậy tôi đang sử dụng dự án để cắt các trường không cần thiết. –

Các vấn đề liên quan