2014-09-15 25 views
10

tài liệu tôi đã có mà trông như thế này:MongoDB tổng hợp (count) trên nhiều lĩnh vực đồng thời

{ 
    "_id" : "someuniqueeventid", 
    "event" : "event_type_1", 
    "date" : ISODate("2014-01-14T00:00:00Z"), 
} 

Tôi muốn nhóm của "event" và đếm có bao nhiêu của từng loại sự kiện xảy ra trong mỗi ngày tuần. Về cơ bản, tôi muốn để có được một cái gì đó như:

{ 
    "_id": "event_type_1", 
    "1": "number of event_type_1 for Monday", 
    "2": "number of event_type_1 for Tuesday", 
    ... 
}, 
{ 
    "_id": "event_type_2", 
    ... 
} 

Thật không may, tôi bị mắc kẹt tại:

db.data.aggregate([ {$project: {date_of_week: {$dayOfWeek: "$date"}, event: "$event"}}, 
        {$group: {_id: "$event", .... } ]) 

ý tưởng Bất kỳ?

Trả lời

15

Khung tổng hợp sẽ không tạo ra các phím dựa trên dữ liệu, cũng không nên bạn thậm chí có thể làm như vậy là "dữ liệu" không phải là một chìa khóa nhưng thực tế dữ liệu, vì vậy bạn nên dính vào mô hình.

Điều đó có nghĩa bạn có thể về cơ bản chỉ làm điều này:

db.data.aggregate([ 
    { "$group": { 
     "_id": { 
      "event_type": "$event", 
      "day": { "$dayOfWeek": "$date" } 
     }, 
     "count": { "$sum": 1 } 
    }} 
]) 

Và đó sẽ đếm số lần xuất hiện mỗi ngày trong tuần cho mỗi sự kiện, mặc dù trong nhiều tài liệu trong đầu ra, nhưng điều này rất dễ dàng để chuyển sang một đơn tài liệu cho mỗi sự kiện:

db.data.aggregate([ 
    { "$group": { 
     "_id": { 
      "event_type": "$event", 
      "day": { "$dayOfWeek": "$date" } 
     }, 
     "count": { "$sum": 1 } 
    }}, 
    { "$group": { 
     "_id": "$_id.event_type", 
     "days": { "$push": { "day": "$day", "count": "$count" } } 
    }} 
]) 

Và tài liệu đó ở dạng mảng, nhưng nó vẫn giữ kết quả bạn muốn.

Nếu bạn đang thực sự thiên lệch về làm hình thức chính xác của bạn sau đó bạn muốn làm một cái gì đó như thế này:

db.data.aggregate([ 
    { "$group": { 
     "_id": "$event", 
     "1": { 
      "$sum": { 
       "$cond": [ 
        { "$eq": [{ "$dayOfWeek": "$date" }, 1 ] }, 
        1, 
        0 
       ] 
      } 
     }, 
     "2": { 
      "$sum": { 
       "$cond": [ 
        { "$eq": [{ "$dayOfWeek": "$date" }, 2 ] }, 
        1, 
        0 
       ] 
      } 
     }, 
     "3": { 
      "$sum": { 
       "$cond": [ 
        { "$eq": [{ "$dayOfWeek": "$date" }, 3 ] }, 
        1, 
        0 
       ] 
      } 
     }, 
     "4": { 
      "$sum": { 
       "$cond": [ 
        { "$eq": [{ "$dayOfWeek": "$date" }, 4 ] }, 
        1, 
        0 
       ] 
      } 
     }, 
     "5": { 
      "$sum": { 
       "$cond": [ 
        { "$eq": [{ "$dayOfWeek": "$date" }, 5 ] }, 
        1, 
        0 
       ] 
      } 
     }, 
     "6": { 
      "$sum": { 
       "$cond": [ 
        { "$eq": [{ "$dayOfWeek": "$date" }, 6 ] }, 
        1, 
        0 
       ] 
      } 
     }, 
     "7": { 
      "$sum": { 
       "$cond": [ 
        { "$eq": [{ "$dayOfWeek": "$date" }, 7 ] }, 
        1, 
        0 
       ] 
      } 
     } 
    }} 
) 

Nhưng đó là thực sự dài hơi để IMHO tôi sẽ gắn bó với giải pháp đầu tiên hoặc có thể thứ hai khi họ ngắn hơn và dễ đọc hơn.

+1

doh! nó có vẻ dễ dàng bây giờ, tôi luôn luôn quên rằng tôi có thể dính nhiều lĩnh vực trong _id: (Cảm ơn! – Unknown

1

Với MongoDb 3.4.4 trở lên, bạn có thể tận dụng việc sử dụng toán tử $arrayToObject để nhận số lượng. Bạn sẽ cần phải chạy đường dẫn tổng hợp sau:

db.data.aggregate([ 
    { 
     "$group": { 
      "_id": { 
       "event": "$event", 
       "day": { "$substr": [ { "$dayOfWeek": "$date" }, 0, -1 ] } 
      }, 
      "count": { "$sum": 1 } 
     } 
    }, 
    { 
     "$group": { 
      "_id": "$_id.event", 
      "counts": { 
       "$push": { 
        "k": "$_id.day", 
        "v": "$count" 
       } 
      } 
     } 
    }, 
    { 
     "$project": { 
      "counts": { "$arrayToObject": "$counts" } 
     } 
    }  
]) 
+1

$ arrayToObject có sẵn bắt đầu với phiên bản 3.4.4. –

+0

@AsyaKamsky Chúc mừng cho làm rõ, cập nhật câu trả lời. – chridam

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