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

Agregat Mongodb, Bagaimana cara menghitung dokumen berdasarkan kriteria interval?

Yang Anda inginkan adalah $cond operator dan beberapa kondisi bersarang dengan $and . Tapi ini akan memberikan apa yang Anda inginkan.

db.collection.aggregate([
    {"$group": {
      "_id": {"$cond": [
          {"$gte": ["$LoadTime", 2000] },
          "Slowest",                                   // return "Slowest" where true
          {"$cond": [
              {"$and": [
                  {"$lt": ["$LoadTime", 2000] },
                  {"$gte": ["$LoadTime", 1000] }
              ]},
              "Slow",                                  // then "Slow" here where true
              {"$cond": [
                  {"$and": [
                      {"$lt": ["$LoadTime", 1000] },
                      {"$gte": ["$LoadTime", 500 ] }
                  ]},
                  "Medium",                            // then "Medium" where true
                  "Fast"                               // and finally "Fast" < 500
              ]}
          ]}
      ]},
      "count": {"$sum": 1}
    }},
    {"$sort": { "count": 1 }}
])

Karena waktu Anda utuh milidetik Anda dapat melihat mengapa saya meminta pengeditan.

Jadi seperti $cond adalah ternary operator, dibutuhkan tiga argumen:

  • Kondisi untuk mengevaluasi yang mengembalikan boolean
  • Nilai yang dikembalikan dengan kondisi true
  • Nilai yang dikembalikan dengan kondisi false

Oleh karena itu, idenya adalah Anda bersarang kondisi di seluruh, pindah ke berikutnya uji pada salah sampai Anda menemukan kondisi yang cocok, dan nilai untuk dikembalikan.

$dan bagian adalah larik kondisi untuk memasukkan. Ini memberi Anda rentang . Jadi di bagian terpanjang:

          {"$cond": [                             // Evaluate here
              {"$and": [                          // Within the range of the next 2
                  {"$lt": ["$LoadTime", 2000] },
                  {"$gte": ["$LoadTime", 1000] }
              ]},
              "Slow",                            // true condition - return
              {"$cond": [                        // false - move to next eval

Mengalir melalui Anda dibiarkan dengan "Cepat" untuk times di bawah 500 milidetik.

Masing-masing keys dipancarkan ke grup dan kami hanya { $sum: 1 } untuk mendapatkan hitungan saat mereka dikelompokkan bersama.

Jika Anda membutuhkannya dalam implementasi bahasa Anda sendiri, seluruh pipeline konten dalam

hanya JSON, jadi Anda dapat menguraikannya ke dalam struktur data asli Anda jika tidak dapat menerjemahkan dengan tangan, atau jika seperti saya, Anda hanya malas.

EDIT

Karena komentar sepertinya perlu untuk menjelaskan formulir dari kueri yang disajikan. Jadi di sini adendum edit untuk klarifikasi.

Saat belajar penggunaan alur agregasi, dan memang praktik yang baik untuk menulis dan menguji serangkaian tahapan atau logika yang kompleks, menurut saya berguna untuk memvisualisasikan hasil dengan menerapkan bagian selangkah demi selangkah . Jadi dalam hal menulis hal seperti itu pertama saya langkahnya adalah sebagai berikut:

db.collection.aggregate([
    {"$group": {
      "_id": {"$cond": [
          {"$gte": ["$LoadTime", 2000] },
          "Slowest",
          null
       ]}
    }}
])

Sekarang itu akan memberi saya hitungan "Paling lambat" seperti yang saya harapkan dan kemudian ember semuanya menjadi null . Jadi ada tahap di mana saya melihat hasilnya sejauh ini. Tapi saat menguji Saya benar-benar akan melakukan sesuatu seperti ini sebelum melanjutkan untuk membangun rantai:

db.collection.aggregate([
    {"$group": {
      "_id": {"$cond": [
          {"$and": [
              {"$lt": ["$LoadTime", 2000] },
              {"$gte": ["$LoadTime", 1000] }
          ]},
          "Slow",
          null
      ]}
    }}
])

Jadi saya hanya mendapatkan hasil untuk "Lambat" (antara 2000 dan 1000) dengan yang lainnya di null keranjang. Jadi jumlah keseluruhan saya tetap sama.

Di final kueri, seperti yang ditunjukkan, dalam ternary kondisi yang bersarang seperti ini, pertama panggung sudah dievaluasi false untuk item yang sedang diuji oleh berikutnya operator. Ini berarti mereka tidak lebih besar dari nilai yang sudah diuji di pertama panggung, dan itu meniadakan kebutuhan untuk menguji kondisi itu sehingga bisa ditulis sebagai berikut:

db.collection.aggregate([
    {"$group": {
      "_id": {"$cond": [
          {"$gte": ["$LoadTime", 2000] },       // Caught everything over 2000
          "Slowest",
          {"$cond": [
              {"$gte": ["$LoadTime", 1000] }    // Catch things still over 1000
              "Slow",
              {"$cond": [                       // Things under 1000 go here

              // and so on

Dan korsleting evaluasi karena tidak ada nyata perlu menguji hal-hal yang tidak akan masuk ke kondisi logis berikutnya.

Jadi murni karena alasan visual dan untuk kemalasan potong dan tempel logika, kita berakhir dengan formulir yang diperluas menggunakan $and syarat untuk membungkus jangkauan. Namun bagi mereka yang tidak terbiasa penggunaan ternary bentuk ada isyarat visual yang jelas bahwa hasil yang dicocokkan dalam fase ini akan berada di antara nilai 2000ms dan 1000ms , dan seterusnya, yang Anda inginkan sebagai hasil di setiap rentang.

Seperti yang saya katakan, tidak perlu memiliki karena cara kerja logika, tetapi itu fase pengembangan, dan jelas kepada orang-orang yang belum mengerti penggunaan ternary bentuk $cond . itu menyediakan.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Kelompokkan Berdasarkan Kondisi di MongoDB

  2. Janji dan driver MongoDB nodejs

  3. MongoDB - Buat Koleksi

  4. NodeJS Knox Formidable menghasilkan 400, File tidak Diunggah ke S3 Bucket

  5. Mongodb di Ubuntu