2013-04-24 34 views
7

Mẫu Tài liệu:MongoDB Aggregation: Tính Totals Chạy từ tổng của hàng trước

{ 
_id: ObjectId('4f442120eb03305789000000'), 
time: ISODate("2013-10-10T20:55:36Z"), 
value:1 
}, 
{ 
_id: ObjectId('4f442120eb03305789000001'), 
time: ISODate("2013-10-10T28:43:16Z"), 
value:2 
}, 
{ 
_id: ObjectId('4f442120eb03305789000002'), 
time: ISODate("2013-10-11T27:12:66Z"), 
value:3 
}, 
{ 
_id: ObjectId('4f442120eb03305789000003'), 
time: ISODate("2013-10-11T10:15:38Z"), 
value:4 
}, 
{ 
_id: ObjectId('4f442120eb03305789000004'), 
time: ISODate("2013-10-12T26:15:38Z"), 
value:5 
} 

Thật dễ dàng để có được kết quả tổng hợp được nhóm theo ngày. Nhưng những gì tôi muốn là để truy vấn kết quả trả về một chạy tổng của tập hợp, như:

{ 
time: "2013-10-10" 
total: 3, 
runningTotal: 3 
}, 
{ 
time: "2013-10-11" 
total: 7, 
runningTotal: 10 
}, 
{ 
time: "2013-10-12" 
total: 5, 
runningTotal: 15 
} 

Đây có phải là có thể với MongoDB Aggregation?

+1

Bạn có thể giữ một số hoạt động như bạn đi cùng. Đó sẽ là cách dễ nhất và hiệu quả nhất, đặc biệt là vì dữ liệu không thay đổi. Khung tổng hợp sẽ là một cách khá đắt tiền để tính toán loại dữ liệu tĩnh này khi đang di chuyển. – cirrus

+1

không có cách nào để thực hiện việc này với khung tổng hợp hiện tại. –

+0

@cirrus Cảm ơn câu trả lời. Tôi không chắc chắn làm thế nào để làm điều đó mặc dù ... – user2315268

Trả lời

2

Điều này thực hiện những gì bạn cần. Tôi đã chuẩn hóa thời gian trong dữ liệu để chúng nhóm lại với nhau (Bạn có thể làm một cái gì đó như this). Ý tưởng là để $group và đẩy timetotal vào các mảng riêng biệt. Sau đó, $unwind mảng time và bạn đã tạo một bản sao của mảng totals cho mỗi tài liệu time. Sau đó bạn có thể tính toán runningTotal (hoặc một cái gì đó giống như trung bình lăn) từ mảng chứa tất cả dữ liệu cho các thời điểm khác nhau. 'Chỉ số' được tạo bởi $unwind là chỉ mục mảng cho số total tương ứng với số time. Điều quan trọng là $sort trước khi $unwind ing vì điều này đảm bảo các mảng theo đúng thứ tự.

db.temp.aggregate(
    [ 
     { 
      '$group': { 
       '_id': '$time', 
       'total': { '$sum': '$value' } 
      } 
     }, 
     { 
      '$sort': { 
       '_id': 1 
      } 
     }, 
     { 
      '$group': { 
       '_id': 0, 
       'time': { '$push': '$_id' }, 
       'totals': { '$push': '$total' } 
      } 
     }, 
     { 
      '$unwind': { 
       'path' : '$time', 
       'includeArrayIndex' : 'index' 
      } 
     }, 
     { 
      '$project': { 
       '_id': 0, 
       'time': { '$dateToString': { 'format': '%Y-%m-%d', 'date': '$time' } }, 
       'total': { '$arrayElemAt': [ '$totals', '$index' ] }, 
       'runningTotal': { '$sum': { '$slice': [ '$totals', { '$add': [ '$index', 1 ] } ] } }, 
      } 
     }, 
    ] 
); 

Tôi đã sử dụng thứ gì đó tương tự trên bộ sưu tập với ~ 80 000 tài liệu, tổng hợp thành 63 kết quả. Tôi không chắc nó sẽ hoạt động tốt như thế nào trên các bộ sưu tập lớn hơn, nhưng tôi thấy rằng việc thực hiện các phép biến đổi (dự đoán, thao tác mảng) trên dữ liệu tổng hợp dường như không có chi phí hiệu năng lớn khi dữ liệu được giảm xuống một kích thước có thể quản lý được.

0

đây là cách tiếp cận khác

đường ống

db.col.aggregate([ 
    {$group : { 
     _id : { time :{ $dateToString: {format: "%Y-%m-%d", date: "$time", timezone: "-05:00"}}}, 
     value : {$sum : "$value"} 
    }}, 
    {$addFields : {_id : "$_id.time"}}, 
    {$sort : {_id : 1}}, 
    {$group : {_id : null, data : {$push : "$$ROOT"}}}, 
    {$addFields : {data : { 
     $reduce : { 
      input : "$data", 
      initialValue : {total : 0, d : []}, 
      in : { 
       total : {$sum : ["$$this.value", "$$value.total"]},     
       d : {$concatArrays : [ 
         "$$value.d", 
         [{ 
          _id : "$$this._id", 
          value : "$$this.value", 
          runningTotal : {$sum : ["$$value.total", "$$this.value"]} 
         }] 
       ]} 
      } 
     } 
    }}}, 
    {$unwind : "$data.d"}, 
    {$replaceRoot : {newRoot : "$data.d"}} 
]).pretty() 

bộ sưu tập

> db.col.find() 
{ "_id" : ObjectId("4f442120eb03305789000000"), "time" : ISODate("2013-10-10T20:55:36Z"), "value" : 1 } 
{ "_id" : ObjectId("4f442120eb03305789000001"), "time" : ISODate("2013-10-11T04:43:16Z"), "value" : 2 } 
{ "_id" : ObjectId("4f442120eb03305789000002"), "time" : ISODate("2013-10-12T03:13:06Z"), "value" : 3 } 
{ "_id" : ObjectId("4f442120eb03305789000003"), "time" : ISODate("2013-10-11T10:15:38Z"), "value" : 4 } 
{ "_id" : ObjectId("4f442120eb03305789000004"), "time" : ISODate("2013-10-13T02:15:38Z"), "value" : 5 } 

kết quả

{ "_id" : "2013-10-10", "value" : 3, "runningTotal" : 3 } 
{ "_id" : "2013-10-11", "value" : 7, "runningTotal" : 10 } 
{ "_id" : "2013-10-12", "value" : 5, "runningTotal" : 15 } 
> 
Các vấn đề liên quan