2014-09-15 20 views
10

bende belgeler üzerinde (sayısı):mongodb agrega Birden fazla alanda şuna benzer eşzamanlı

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

ben "event" göre gruplandırmak istediğiniz ve her bir günü meydana her olay türünün kaç saymak hafta. Temelde, böyle bir şey almak istiyorum:

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

Herhangi fikirler: Maalesef

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

, ben mahsur kaldım? Eğer desen tutması gerektiğini bu nedenle

cevap

15

toplama çerçeve verilerine dayanarak tuşları oluşturmaz, ne hatta "veri" olarak bunu yaparken gerektiğini, anahtar ama aslında veri değil.

temelde sadece bunu yapabilirsiniz demektir

:

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

Ve bu çıktıda birden belgelerde de olsa etkinlik başına haftanın, günde oluşumlarını saymak, ancak bu tek değiştirmek kolaydır Olay başına belge:

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" } } 
    }} 
]) 

Ve bu bir dizi biçimindedir, ancak yine de istediğiniz sonuçları tutar.

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 
       ] 
      } 
     } 
    }} 
) 

Ama bu gerçekten uzun böylece IMHO ben de onlar kadar birinci ya da belki ikinci solüsyon ile sadık kalacağına sarılır: o zaman böyle bir şey yapmak istiyorum tam formunu yapıyor gerçekten bükük varsa

okumak daha kısa ve daha kolaydır.

+1

doh! Şimdi kolay görünüyor, ben her zaman _id içinde birden fazla alan yapışabilirim unutuyorum :(Teşekkür! – Unknown

1

MongoDb 3.4.4 ve daha yenisi ile, sayıları almak için $arrayToObject operatörünün kullanımından yararlanabilirsiniz. Aşağıdaki toplam boru hattını çalıştırmanız gerekir:

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 sürüm 3.4.4 ile başlayan kullanılabilir. –

+0

@AsyaKamsky Arındırma, güncellenmiş cevap için alkış. – chridam

İlgili konular