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

Kondisi Pencocokan Anggota Array Jumlah Agregat

Kesalahannya adalah karena ini bukan lagi array setelah Anda $unwind dan karenanya tidak lagi menjadi argumen yang valid untuk $size .

Anda tampaknya mencoba untuk "menggabungkan" beberapa jawaban yang ada tanpa memahami apa yang mereka lakukan. Yang Anda inginkan di sini adalah $filter dan $size

db.collection.aggregate([
  { "$project": {
    "total": {
      "$size": {
        "$filter": {
          "input": "$Array",
          "cond": { "$eq": [ "$$this.field1", "a" ] }
        }
      }
    }
  }}
])

Atau "temukan kembali roda" menggunakan $reduce :

db.collection.aggregate([
  { "$project": {
    "total": {
      "$reduce": {
        "input": "$Array",
        "initialValue": 0,
        "in": {
          "$sum": [
            "$$value", 
            { "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
        }
      }
    }
  }}
])

Atau untuk apa yang Anda coba lakukan dengan $unwind , Anda sebenarnya $group lagi untuk "menghitung" berapa banyak kecocokan yang ada:

db.collection.aggregate([
  { "$unwind": "$Array" },
  { "$match": { "Array.field1": "a" } },
  { "$group": {
    "_id": "$_id",
    "total": { "$sum": 1 }
  }}
])

Dua bentuk pertama adalah "optimal" untuk lingkungan MongoDB modern. Formulir terakhir dengan $unwind dan $group adalah konstruksi "warisan" yang sebenarnya tidak diperlukan untuk jenis operasi ini sejak MongoDB 2.6, meskipun dengan beberapa operator yang sedikit berbeda.

Dalam dua yang pertama kami pada dasarnya membandingkan field1 nilai setiap elemen array saat masih berupa array. Keduanya $filter dan $reduce adalah operator modern yang dirancang untuk bekerja dengan susunan yang sudah ada. Perbandingan yang sama dilakukan pada masing-masing menggunakan agregasi $eq operator yang mengembalikan nilai boolean berdasarkan apakah argumen yang diberikan "sama" atau tidak. Dalam hal ini pada setiap anggota array dengan nilai yang diharapkan dari "a" .

Dalam kasus $filter , array sebenarnya tetap utuh kecuali untuk elemen apa pun yang tidak memenuhi kondisi yang disediakan di "cond" akan dihapus dari array. Karena kita masih memiliki "array" sebagai output, kita dapat menggunakan $ukuran operator untuk mengukur jumlah elemen larik yang tersisa setelah kondisi filter tersebut diproses.

$reduce di sisi lain bekerja melalui elemen array dan memasok ekspresi di setiap elemen dan nilai "akumulator" yang tersimpan, yang kami inisialisasi dengan "initialValue" . Dalam hal ini $eq yang sama pengujian diterapkan dalam $cond operator. Ini adalah "ternary" atau if/then/else operator kondisional yang memungkinkan ekspresi yang diuji yang mengembalikan nilai boolean untuk mengembalikan then nilai ketika true atau else nilai ketika false .

Dalam ekspresi itu kami mengembalikan 1 atau 0 masing-masing dan berikan hasil keseluruhan dari penambahan nilai yang dikembalikan dan "akumulator" saat ini "$$value" dengan $sum operator untuk menambahkan ini bersama-sama.

Formulir terakhir menggunakan $unwind pada larik. Apa yang sebenarnya dilakukan adalah mendekonstruksi anggota array untuk membuat "dokumen baru" untuk setiap anggota array dan bidang induk terkait dalam dokumen asli. Ini secara efektif "menyalin" dokumen utama untuk setiap anggota array.

Setelah Anda $unwind struktur dokumen diubah menjadi bentuk yang "lebih datar". Inilah sebabnya mengapa Anda kemudian dapat melakukan $match tahap pipa untuk menghapus dokumen yang tidak cocok.

Ini membawa kita ke $group yang diterapkan untuk "mengumpulkan kembali" semua informasi yang terkait dengan kunci umum. Dalam hal ini adalah _id bidang dokumen asli, yang tentu saja disalin ke setiap dokumen yang dihasilkan oleh $unwind . Saat kita kembali ke "kunci umum" ini sebagai satu dokumen, kita dapat "menghitung" sisa "dokumen" yang diekstrak dari larik menggunakan $sum akumulator.

Jika kami menginginkan "array" yang tersisa kembali, Anda dapat $dorong dan bangun kembali array hanya dengan anggota yang tersisa:

  { "$group": {
    "_id": "$_id",
    "Array": { "$push": "$Array" },
    "total": { "$sum": 1 }
  }}

Tapi tentu saja daripada menggunakan $size di tahap pipa lain, kita masih bisa "menghitung" seperti yang sudah kita lakukan dengan $sum




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bagaimana cara mengubah kata sandi pengguna mongoDB saya sebagai non administrator?

  2. Mongoid 3 + Heroku (MongoHQ) menyebabkan Moped::Errors::OperationFailure

  3. Bagaimana cara mengonversi format tanggal di mongodb

  4. Mengumumkan ClusterControl 1.4.2 - Edisi DevOps

  5. mongo menemukan kueri di joda datetime