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

Mongodb - kueri total hari ini, total minggu, dan total bulan dalam satu kueri

Ini lebih merupakan pertanyaan tentang seperti apa hasil yang Anda harapkan, karena hasil agregat apa pun pada dasarnya perlu dikelompokkan pada level terendah dan kemudian secara progresif mengelompokkan pada "biji-bijian" yang lebih tinggi hingga level terbesar ( "bulan" ) tercapai. Jenis ini menyiratkan data yang pada akhirnya dikelompokkan berdasarkan "bulan", kecuali jika Anda mengelompokkannya sebaliknya.

Intinya, secara bertahap $group :

db.collection.aggregate([
    // First total per day. Rounding dates with math here
    { "$group": {
        "_id": {
            "$add": [
                { "$subtract": [
                    { "$subtract": [ "$createdAt", new Date(0) ] },
                    { "$mod": [
                        { "$subtract": [ "$createdAt", new Date(0) ] },
                        1000 * 60 * 60 * 24
                    ]}                        
                ]},
                new Date(0)
            ]
        },
        "week": { "$first": { "$week": "$createdAt" } },
        "month": { "$first": { "$month": "$createdAt" } },
        "total": { "$sum": "$num" }
    }},

    // Then group by week
    { "$group": {
        "_id": "$week",
        "month": { "$first": "$month" },
        "days": {
            "$push": {
                "day": "$_id",
                "total": "$total"
            }
        },
        "total": { "$sum": "$total" }
    }},

    // Then group by month
    { "$group": {
        "_id": "$month",
        "weeks": {
            "$push": {
                "week": "$_id",
                "total": "$total",
                "days": "$days"
            }
        },
        "total": { "$sum": "$total" }
    }}
])

Jadi setiap level setelah yang pertama yang dijumlahkan per hari kemudian secara bertahap didorong ke dalam konten array untuk nilai "pembulatan" dan totalnya kemudian dijumlahkan pada level itu juga.

Jika Anda menginginkan hasil yang lebih datar dengan satu catatan per hari yang berisi total mingguan dan bulanan serta total hari, cukup tambahkan dua $unwind pernyataan sampai akhir pipeline:

{ "$unwind": "$weeks" },
{ "$unwind": "$weeks.days" }

Dan opsional $project bidang "bertitik" menjadi sesuatu yang lebih datar dan dapat dibaca jika Anda harus.

Jika Anda merentangkan "tahun" dengan ini, maka sertakan operasi seperti itu dalam kunci pengelompokan setidaknya dari tingkat "minggu" sehingga Anda tidak mungkin menggabungkan data dari tahun yang berbeda dan data tersebut dipisahkan.

Ini juga merupakan preferensi umum saya sendiri untuk menggunakan "matematika tanggal" pendekatan saat membulatkan tanggal karena mengembalikan Date objek, tetapi seperti yang digunakan pada level selain "hari", Anda dapat menggunakan operator agregasi tanggal sebagai gantinya.

Tidak perlu mapReduce karena ini cukup intuitif dan ada jumlah hari yang terbatas dalam sebulan itu berarti batas BSON saat menyusun array dalam konten saat menggabungkan tidak akan rusak.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Tidak dapat mengautentikasi pengguna di MongoDB 3.0.2 menggunakan koneksi java

  2. Gunakan lebih dari satu skema per koleksi di mongodb

  3. Bagaimana saya bisa memperbarui satu dokumen di array bersarang?

  4. Koneksi Mongo ditutup di aplikasi keystonejs

  5. Bagaimana cara menggunakan kueri geospasial di driver 2.1 MongoDB C#?