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

Bagaimana saya bisa $addToSet objek ke array dan $sort juga menggunakan MongoDB?

Anda adalah bagian dari perjalanan ke sana dengan mengidentifikasi operasi yang perlu Anda lakukan dengan benar. Tapi tentu saja $sort bukan pengubah yang valid untuk $addToSet karena mantra MongoDB adalah "set tidak dianggap dipesan" :

Masalah lain di sini seperti yang ditunjukkan oleh kesalahan adalah Anda tidak dapat menggunakan beberapa operator pembaruan (seperti $addToSet dan $push ) pada jalur yang sama ke properti pada waktu yang sama. Sebenarnya ada "tidak ada perintah" untuk eksekusi dari operator pembaruan yang berbeda, jadi mereka tidak menjamin bahwa $addToSet terjadi sebelum $push . Bahkan mereka cenderung bertindak secara paralel, itulah sebabnya kesalahan dan ini tidak diperbolehkan.

Jawabannya tentu saja adalah pernyataan pembaruan "dua". Satu untuk $addToSet dan satu untuk menerapkan $sort dengan "mendorong" array kosong melalui $each ,

Tetapi karena kami benar-benar tidak ingin "menunggu" setiap pembaruan selesai, inilah gunanya API operasi "Bulk". Jadi Anda dapat mengirim kedua instruksi ke server dalam satu kirim dan dapatkan satu tanggapan:

var bulk = db.perros.initializeOrderedBulkOp();
bulk.find({ "name": "Risas" }).update({ 
   "$addToSet": { 
       "propiedades": { "name": "cola", "cantidad": 1 }
   }
});
bulk.find({ "name": "Risas" }).update({ 
   "$push": { 
       "propiedades": { 
           "$each": [ ], "$sort": { "cantidad": -1 } 
        }
   }
});
bulk.execute();

Jadi ini benar-benar masih hanya satu permintaan ke server dan satu tanggapan. Ini masih "dua" operasi tetapi overhead dan kemungkinan beberapa utas mengambil status sementara pembaruan dapat diabaikan.

Ada alternatif untuk pendekatan ini yaitu dengan memindahkan logika "set deteksi" ke dalam .find() bagian dari pernyataan pembaruan dan kemudian cukup terapkan $push di mana anggota yang akan ditambahkan ke "set" belum ada:

var bulk = db.perros.initializeOrderedBulkOp();
bulk.find({ 
    "name": "Risas", 
    "propiedades": { 
        "$not": { "$elemMatch": { "name": "cola", "cantidad": 1 } } 
    } 
}).update({ 
   "$push": { 
       "propiedades": { 
           "$each": [{ "name": "cola", "cantidad": 1 }], "$sort": { "cantidad": -1 } 
        }
   }
});
bulk.execute();

Tentu saja komplikasinya adalah jika Anda menambahkan elemen array "beberapa" di sini, Anda perlu membungkus $not dan $elemMacth pengujian dalam $and kondisi, dan kemudian jika "hanya satu" dari elemen tersebut valid maka tidak dapat ditambahkan sendiri.

Anda dapat "mencoba" operasi semacam itu dengan "beberapa" item "pertama", tetapi kemudian Anda harus memiliki eksekusi "fallback" dari setiap elemen array individual dengan logika yang sama seperti di atas untuk "menguji" kemungkinan "mendorong" untuk masing-masing elemen.

Jadi $addToSet membuat bagian kedua itu mudah dengan beberapa entri array. Untuk satu entri, cukup sederhana untuk hanya "meminta" dan $push , untuk lebih dari satu mungkin jalur yang lebih pendek untuk menggunakan pola "pertama" dengan $addToSet dan $push array kosong untuk "mengurutkan" hasil karena menerapkan pola kedua berarti tetap melakukan beberapa tes pembaruan.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bagaimana cara memproyeksikan nilai yang diperbarui hanya menggunakan findOneAndUpdate dalam array tersemat Mongoose?

  2. MongoDB/Mongoose - Menanyakan array objek berdasarkan tanggal

  3. Cara memformat data dalam Model sebelum menyimpan di Mongoose (ExpressJS)

  4. Gabungkan hasil MongoDB berdasarkan tanggal ObjectId

  5. Cara memasukkan objek baru tanpa menghapus yang sebelumnya