2012-07-10 32 views
26

Tôi muốn sử dụng Aggregation Khung MongoDB để chạy những gì trong SQL sẽ trông hơi giống:Khung tập hợp Mongodb | Nhóm trên nhiều giá trị?

SELECT SUM(A), B, C from myTable GROUP BY B, C; 

Các tài liệu nhà nước:

Bạn có thể chỉ định một lĩnh vực duy nhất từ ​​các tài liệu trong các đường ống , giá trị được tính trước đó hoặc khóa tổng hợp được tạo thành từ một số trường đến.

Nhưng không rõ 'một khóa tổng hợp được làm từ nhiều trường đến' thực sự là gì?

bộ dữ liệu của tôi là một chút như thế này:

[{ "timeStamp" : 1341834988666, "label" : "sharon", "responseCode" : "200", "value" : 10, "success" : "true"}, 
{ "timeStamp" : 1341834988676, "label" : "paul", "responseCode" : "200", "value" : 60, "success" : "true"}, 
{ "timeStamp" : 1341834988686, "label" : "paul", "responseCode" : "404", "value" : 15, "success" : "true"}, 
{ "timeStamp" : 1341834988696, "label" : "sharon", "responseCode" : "200", "value" : 35, "success" : "false"}, 
{ "timeStamp" : 1341834988166, "label" : "paul", "responseCode" : "200", "value" : 40, "success" : "true"}, 
{ "timeStamp" : 1341834988266, "label" : "paul", "responseCode" : "404", "value" : 99, "success" : "false"}] 

truy vấn của tôi trông như thế này:

resultsCollection.aggregate(
    { $match : { testid : testid} }, 
    { $skip : alreadyRead }, 
    { $project : { 
      timeStamp : 1 , 
      label : 1, 
      responseCode : 1 , 
      value : 1, 
      success : 1 
     }}, 
    { $group : { 
      _id : "$label", 
      max_timeStamp : { $timeStamp : 1 }, 
      count_responseCode : { $sum : 1 }, 
      avg_value : { $sum : "$value" }, 
      count_success : { $sum : 1 } 
     }}, 
    { $group : { 
      ? 
     }} 
); 

bản năng của tôi là cố gắng ống các kết quả thông qua một nhóm thứ hai, tôi biết bạn có thể làm điều này nhưng nó sẽ không hoạt động vì nhóm đầu tiên đã giảm số liệu quá nhiều và mức độ chi tiết bắt buộc bị mất.

Điều tôi muốn làm là nhóm sử dụng label, responseCodesuccess và nhận tổng giá trị từ kết quả. Nó sẽ giống một chút như:

label | code | success | sum_of_values | count 
sharon | 200 | true |  10  | 1 
sharon | 200 | false |  35  | 1 
paul | 200 | true |  100  | 2 
paul | 404 | true |  15  | 1 
paul | 404 | false |  99  | 1 

đâu có năm nhóm:

1. { "timeStamp" : 1341834988666, "label" : "sharon", "responseCode" : "200", "value" : 10, "success" : "true"} 

2. { "timeStamp" : 1341834988696, "label" : "sharon", "responseCode" : "200", "value" : 35, "success" : "false"} 

3. { "timeStamp" : 1341834988676, "label" : "paul", "responseCode" : "200", "value" : 60, "success" : "true"} 
    { "timeStamp" : 1341834988166, "label" : "paul", "responseCode" : "200", "value" : 40, "success" : "true"} 

4. { "timeStamp" : 1341834988686, "label" : "paul", "responseCode" : "404", "value" : 15, "success" : "true"} 

5. { "timeStamp" : 1341834988266, "label" : "paul", "responseCode" : "404", "value" : 99, "success" : "false"} 

Trả lời

37

OK, vì vậy giải pháp là để xác định một chính tổng hợp cho các giá trị _id. Đây là tài liệu here như:

Bạn có thể chỉ định một lĩnh vực duy nhất từ ​​các tài liệu trong các đường ống, một giá trị tính toán trước đó, hoặc một chính tổng hợp tạo thành từ nhiều lĩnh vực đến.

Nhưng nó không thực sự xác định định dạng cho khóa tổng hợp. Đọc tài liệu trước đó here Tôi thấy rằng phương pháp collection.group trước đó có thể lấy nhiều trường và cấu trúc tương tự được sử dụng trong khung công tác mới.

Vì vậy, để nhóm trên nhiều lĩnh vực mà bạn có thể sử dụng _id : { success:'$success', responseCode:'$responseCode', label:'$label'}

Như trong:

resultsCollection.aggregate(
{ $match : { testid : testid} }, 
{ $skip : alreadyRead }, 
{ $project : { 
     timeStamp : 1 , 
     label : 1, 
     responseCode : 1 , 
     value : 1, 
     success : 1 
    }}, 
{ $group : { 
     _id : { success:'$success', responseCode:'$responseCode', label:'$label'}, 
     max_timeStamp : { $timeStamp : 1 }, 
     count_responseCode : { $sum : 1 }, 
     avg_value : { $sum : "$value" }, 
     count_success : { $sum : 1 } 
    }} 
); 
+1

mục đích của $ dự án của bạn là gì? liệu tài liệu gốc có lớn hơn nhiều không? cũng bỏ qua không có ý nghĩa nhiều mà không có một loại trước khi nó. và nếu bạn cần avg_value tại sao không sử dụng $ avg? nếu bạn muốn tổng hợp tại sao không gọi nó là sum_value? Ngoài ra count_success và count_responseCode sẽ giống nhau, không chắc chắn tại sao bạn cần cả hai. –

+9

Lưu ý: Khi có 2.2.0-rc1 thay đổi nhỏ đã được thực hiện để nhóm theo nhiều trường: _id: {success: 1, responseCode: 1, label: 1} sẽ trở thành _id: {success: "$ success", responseCode: "$ responseCode", nhãn: "$ label"}. https://groups.google.com/forum/?fromgroups#!topic/mongodb-user/1cYch580h0w – Richard

+1

câu trả lời được sửa theo @Richard. –

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