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

Menggunakan Nilai Dinamis dalam Agregasi

Pertanyaan umum di sini adalah memasukkan rentang untuk "month" nilai dalam pertimbangan di mana itu "lebih besar dari" -5 bulan "sebelum" dan "kurang dari" +2 bulan "setelah" sebagaimana dicatat dalam "enrolled" entri larik.

Masalahnya adalah karena nilai ini didasarkan pada "dateJoined" , mereka perlu disesuaikan dengan interval yang benar antara "dateJoined" dan "dateActivated" . Ini membuat ekspresi efektif:

monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)

where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"

Atau dinyatakan secara logis "Bulan antara rentang yang dinyatakan disesuaikan dengan jumlah bulan perbedaan antara bergabung dan mengaktifkan" .

Seperti yang dinyatakan dalam komentar, hal pertama yang perlu Anda lakukan di sini adalah menyimpan nilai tanggal tersebut sebagai BSON Date sebagai lawan dari nilai "string" mereka saat ini. Setelah selesai, Anda kemudian dapat menerapkan agregasi berikut untuk menghitung perbedaan dari tanggal yang diberikan dan memfilter rentang yang disesuaikan dari larik sebelum menghitung:

var rangeStart = -5,
    rangeEnd = 2;

db.getCollection('enrollments').aggregate([
  { "$project": {
    "enrollments": {
      "$size": {
        "$filter": {
          "input": "$enrolled",
          "as": "e",
          "cond": {
            "$let": {
              "vars": {
                "monthsDiff": {
                  "$add": [
                    { "$multiply": [
                      { "$subtract": [
                        { "$year": "$dateActivated" },
                        { "$year": "$dateJoined" }
                      ]},
                      12
                    }},
                    { "$subtract": [
                      { "$month": "$dateActivated" },
                      { "$month": "$dateJoined" }
                    ]}
                  ]
                }
              },
              "in": {
                "$and": [
                  { "$gte": [ { "$add": [ rangeStart, "$$monthsDiff" ] }, "$$e.month" ] },
                  { "$lte": [ { "$add": [ rangeEnd, "$$monthsDiff" ] }, "$$e.month" ] },
                  { "$eq": [ "$$e.enrolled", "01" ] }
                ]
              }
            }
          } 
        }
      }
    }
  }}
])

Jadi ini berlaku sama $filter ke larik yang Anda coba, tetapi sekarang memperhitungkan nilai yang disesuaikan pada rentang bulan untuk difilter juga.

Untuk membuatnya lebih mudah dibaca, kami menerapkan $let yang memungkinkan penghitungan nilai umum yang diperoleh untuk $$monthsDiff seperti yang diimplementasikan dalam sebuah variabel. Di sinilah ekspresi yang dijelaskan awalnya diterapkan, menggunakan $year dan $month untuk mengekstrak nilai numerik tersebut dari tanggal yang disimpan.

Menggunakan operator matematika tambahan $add , $subtract dan $multiply Anda dapat menghitung perbedaan dalam bulan dan juga kemudian menerapkan untuk menyesuaikan nilai "rentang" dalam kondisi logis dengan $gte dan $lte .

Akhirnya, karena $filter memancarkan array hanya entri yang cocok dengan kondisi, untuk "menghitung" kami menerapkan $size yang mengembalikan panjang larik "terfilter", yang merupakan "jumlah" kecocokan.

Bergantung pada tujuan yang Anda maksudkan, seluruh ekspresi juga dapat diberikan dalam argumen ke $sum sebagai $group akumulator, jika memang itu niatnya.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bidang deserialisasi saat jenis diubah menggunakan driver csharp MongoDb

  2. Cara mengkonfigurasi Monolog untuk menyimpan log ke MongoDB dengan Symfony2 dan Doctrine

  3. Masalah dengan CORS. Labu <-> AngularJS

  4. mongo.so:> simbol tidak terdefinisi:php_json_encode in Unknown on line 0. Setelah instalasi driver mongo untuk php

  5. Spring dan MongoDB:SAXParseException saat membaca Definisi Kacang