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

MongoDB - $set untuk memperbarui atau mendorong elemen Array

Sebenarnya melakukan apa yang Anda katakan sedang Anda lakukan bukanlah operasi tunggal, tetapi saya akan membahas bagian-bagian yang diperlukan untuk melakukan ini atau menutupi kemungkinan situasi lain.

Apa yang Anda cari sebagian adalah $ . posisional operator. Anda memerlukan bagian dari kueri Anda untuk juga "menemukan" elemen larik yang Anda inginkan.

db.products.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        "$set": { 
            "recentviews.$.vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    }
)

Jadi $ singkatan dari posisi yang cocok dalam larik sehingga bagian pembaruan mengetahui item mana dalam larik yang akan diperbarui. Anda dapat mengakses masing-masing bidang dokumen dalam larik atau hanya menentukan seluruh dokumen yang akan diperbarui pada posisi itu.

db.products.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        "$set": { 
            "recentviews.$": {
                 "viewedby": "abc",
                 "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    }
)

Jika field sebenarnya tidak berubah dan Anda hanya ingin menyisipkan elemen array baru jika elemen yang sama persis tidak ada, maka Anda dapat menggunakan $addToSet

db.products.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        $addToSet:{ 
            "recentviews": {
                 "viewedby": "abc",
                 "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    }
)

Namun jika Anda hanya mencari "mendorong" ke array dengan nilai kunci tunggal jika itu tidak ada maka Anda perlu melakukan penanganan manual lagi, dengan terlebih dahulu melihat apakah elemen dalam array ada dan kemudian membuat $push pernyataan di mana tidak.

Anda mendapatkan bantuan dari metode luwak dalam melakukan ini dengan melacak jumlah dokumen yang terpengaruh oleh pembaruan:

Product.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        "$set": { 
            "recentviews.$": {
                 "viewedby": "abc",
                 "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    },
    function(err,numAffected) {

        if (numAffected == 0) {
            // Document not updated so you can push onto the array
            Product.update(
                { 
                    "_id": ObjectId("536c55bf9c8fb24c21000095")
                },
                { 
                    "$push": { 
                        "recentviews": {
                            "viewedby": "abc",
                            "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
                        }
                    }
                },
                function(err,numAffected) {

                }
            );
        }            

    }
);

Satu-satunya peringatan di sini adalah bahwa ada sedikit perubahan implementasi dalam pesan writeConcern dari MongoDB 2.6 ke versi sebelumnya. Tidak yakin sekarang tentang bagaimana API luwak sebenarnya mengimplementasikan kembalinya numAffected argumen dalam panggilan balik perbedaannya bisa berarti sesuatu.

Di versi sebelumnya, bahkan jika data yang Anda kirim di pembaruan awal sama persis dengan elemen yang ada dan tidak ada perubahan nyata yang diperlukan, maka jumlah yang "dimodifikasi" akan dikembalikan sebagai 1 meskipun tidak ada yang benar-benar diperbarui.

Dari MongoDB 2.6, respons kekhawatiran penulisan berisi dua bagian. Satu bagian menunjukkan dokumen yang dimodifikasi dan yang lainnya menunjukkan kecocokan. Jadi sementara kecocokan akan dikembalikan oleh bagian kueri yang cocok dengan elemen yang ada, jumlah dokumen yang dimodifikasi sebenarnya akan kembali sebagai 0 jika sebenarnya tidak ada perubahan yang diperlukan.

Jadi tergantung pada bagaimana nomor pengembalian sebenarnya diterapkan di luwak, mungkin sebenarnya lebih aman menggunakan $addToSet operator pada pembaruan dalam untuk memastikan bahwa jika alasan nol dokumen yang terpengaruh bukan hanya karena elemen persisnya sudah ada.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Luwak Tidak Dapat Terhubung Tanpa Internet

  2. Luwak findOneAndUpdate dan upsert tidak mengembalikan kesalahan, tidak ada dokumen yang terpengaruh

  3. Memesan hasil yang ditetapkan secara acak di mongo

  4. Spring Data Mongo - terapkan bidang kombinasi unik dalam dokumen yang disematkan

  5. MongoDB:perbarui setiap dokumen di satu bidang