MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Агрегиране на Mongodb по ден и след това по час

Това, което основно искате, е двойно групиране, но не получавате обратно целия обект за дата, като използвате оператори за агрегиране на дати , само съответните части:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "customerId": "$customerId",
            "day": { "$dayOfYear": "$startTime" },
            "hour": { "$hour": "$startTime" }
        },
        "pings": { "$sum": "$ping" },
        "links": { "$sum": "$link" }
    }},
    { "$group": {
       "_id": {
           "customerId": "$_id.customerId",
           "day": "$_id.day"
       },
       "hours": { 
           "$push": { 
               "hour": "$_id.hour",
               "pings": "$pings",
               "links": "$links"
           }
       }
    }}
])

Двойният $group ви дава формата, който искате, като поставя резултатите в масив на ден. Единичен документ в извадката, но основно получавате резултати като тези:

{
    "_id" : {
            "customerId" : 123,
            "day" : 365
    },
    "hours" : [
            {
                    "hour" : 10,
                    "pings" : 2,
                    "links" : 3
            }
    ]
}

Ако смятате, че резултатите от операторите за дата са трудни за работа или искате опростен резултат за „преминаване“ за обекти за дата, тогава можете вместо това да прехвърлите като клеймо за време:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "customerId": "$customerId",
            "day": {
               "$subtract": [
                   { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                   {
                       "$mod": [
                           { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                           1000*60*60*24   
                       ]
                   }
               ]
            },
            "hour": {
               "$subtract": [
                   { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                   {
                       "$mod": [
                           { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                           1000*60*60   
                       ]
                   }
               ]
            }
        },
        "pings": { "$sum": "$ping" },
        "links": { "$sum": "$link" }
    }},
    { "$group": {
       "_id": {
           "customerId": "$_id.customerId",
           "day": "$_id.day"
       },
       "hours": { 
           "$push": { 
               "hour": "$_id.hour",
               "pings": "$pings",
               "links": "$links"
           }
       }
    }}
])

Номерът там е, когато $subtract един обект за дата от друг получавате обратно стойността "епоха" като резултат. В този случай използваме началната дата на „епохата“, за да получим цялата стойност на клеймото за време и просто предоставяме „математика за дата“, за да коригираме времената към необходимите интервали. Така че резултатът:

{
    "_id" : {
            "customerId" : 123,
            "day" : NumberLong("1419984000000")
    },
    "hours" : [
            {
                    "hour" : NumberLong("1420020000000"),
                    "pings" : 2,
                    "links" : 3
            }
    ]
}

Което може да е по-приятно за вас от това, което операторите за дата предоставят като резултат в зависимост от вашите нужди.

Можете също така да добавите малко съкращения за това с MongoDB 2.6 чрез $let оператор, който ви позволява да декларирате "променливи" за операции с обхват:

db.event.aggregate([
    { "$group": {
        "_id": {
            "$let": {
                "vars": { 
                   "date": { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                   "day": 1000*60*60*24,
                   "hour": 1000*60*60
                },
                "in": {
                    "customerId": "$customerId",
                    "day": {
                        "$subtract": [
                            "$$date",
                            { "$mod": [ "$$date", "$$day" ] }
                         ]
                    },
                    "hour": {
                        "$subtract": [
                            "$$date",
                            { "$mod": [ "$$date", "$$hour" ] }
                         ]
                    }
                }
            }
        },
        "pings": { "$sum": "$ping" },
        "links": { "$sum": "$link" }
    }},
    { "$group": {
       "_id": {
           "customerId": "$_id.customerId",
           "day": "$_id.day"
       },
       "hours": { 
           "$push": { 
               "hour": "$_id.hour",
               "pings": "$pings",
               "links": "$links"
           }
       }
    }}
])

Също така почти забравих да спомена, че вашите стойности за "ping" и "link" всъщност са низове, освен ако това не е правописна грешка. Но ако не, първо се уверете, че сте ги преобразували като числа.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Вземане на сума от колона в MongoDB

  2. изберете отделен mongodb C#

  3. Надграждането на mongodb няма ефект и все още показва старата версия

  4. конфигурация максимален стар размер на пространството в Nodejs

  5. TypeError при статичен метод на мангуст модел