MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Agregasi Mongodb berdasarkan Hari lalu Jam

Apa yang pada dasarnya Anda inginkan adalah pengelompokan ganda, tetapi Anda tidak mendapatkan seluruh objek tanggal kembali menggunakan operator agregasi tanggal , hanya bagian yang relevan:

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

Ganda $group memberi Anda format yang Anda inginkan dengan menempatkan hasilnya ke dalam array per hari. Dokumen tunggal dalam sampel, tetapi pada dasarnya Anda mendapatkan hasil seperti ini:

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

Jika Anda menemukan hasil dari operator tanggal sulit untuk ditangani atau menginginkan hasil "pass-through" yang disederhanakan untuk objek tanggal, maka Anda dapat menggunakan stempel waktu Epoch sebagai gantinya:

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

Trik di sana adalah ketika Anda $subtract satu objek tanggal dari yang lain Anda mendapatkan nilai "Epoch" kembali sebagai hasilnya. Dalam hal ini kami menggunakan tanggal mulai "Epoch" untuk mendapatkan seluruh nilai stempel waktu dan hanya menyediakan "matematika tanggal" untuk mengoreksi waktu ke interval yang diperlukan. Jadi hasilnya:

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

Yang mungkin lebih cocok untuk Anda daripada yang disediakan oleh operator tanggal, tergantung pada kebutuhan Anda.

Anda juga dapat menambahkan sedikit singkatan untuk ini dengan MongoDB 2.6 melalui $let operator yang memungkinkan Anda mendeklarasikan "variabel" untuk operasi tercakup:

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

Saya juga hampir lupa menyebutkan bahwa nilai Anda untuk "ping" dan "tautan" sebenarnya adalah string kecuali itu salah ketik. Tetapi jika tidak, pastikan Anda mengonversinya sebagai angka terlebih dahulu.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bagaimana cara membatasi ukuran array di MongoDB?

  2. Batas waktu koneksi ke MongoDb di Azure VM

  3. Luwak dengan ReplicaSet di Atlas

  4. membuat formulir pendaftaran dan login di node.js dan mongodb

  5. Bagaimana saya bisa menangani persimpangan larik di find({})?