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

Denormalisasi dengan Mongoose:Cara menyinkronkan perubahan

Oke, sembari menunggu jawaban yang lebih baik dari jawaban saya sendiri, saya akan mencoba memposting apa yang telah saya lakukan selama ini.

Perangkat Tengah Sebelum/Pasca

Hal pertama yang saya coba adalah menggunakan pre/post middlewares untuk menyinkronkan dokumen yang direferensikan satu sama lain. (Misalnya, jika Anda memiliki Author dan Quote , dan Penulis memiliki larik dengan tipe:quotes: [{type: Schema.Types.ObjectId, ref:'Quotes'}] , maka setiap kali Kutipan dihapus, Anda harus menghapus _id .nya dari larik. Atau jika Penulis dihapus, Anda mungkin ingin semua kutipannya dihapus).

Pendekatan ini memiliki keuntungan yang penting :jika Anda mendefinisikan setiap Skema dalam filenya sendiri, Anda dapat menentukan middleware di sana dan membuat semuanya teratur dengan rapi . Setiap kali Anda melihat skema, tepat di bawah Anda dapat melihat apa yang dilakukannya, bagaimana perubahannya memengaruhi entitas lain, dll:

var Quote = new Schema({
    //fields in schema
})
//its quite clear what happens when you remove an entity
Quote.pre('remove', function(next) {
    Author.update(
        //remove quote from Author quotes array.
    )
})

Kerugian utama namun kait ini tidak dijalankan saat Anda memanggil pembaruan atau fungsi pembaruan/penghapusan statis Model apa pun . Sebaliknya Anda perlu mengambil dokumen dan kemudian memanggil save() atau remove() pada mereka.

Kerugian lain yang lebih kecil adalah Quote sekarang perlu mengetahui siapa saja yang mereferensikannya, sehingga dapat memperbaruinya setiap kali Quote diperbarui atau dihapus. Jadi katakanlah sebuah Period memiliki daftar kutipan, dan Author memiliki daftar kutipan juga, Kutipan perlu mengetahui tentang keduanya untuk memperbaruinya.

Alasan untuk ini adalah bahwa fungsi-fungsi ini mengirim kueri atom ke database secara langsung. Meskipun ini bagus, saya benci inkonsistensi antara menggunakan save() dan Model.Update(...) . Mungkin orang lain atau Anda di masa mendatang secara tidak sengaja menggunakan fungsi pembaruan statis dan middleware Anda tidak terpicu, membuat Anda sakit kepala dan sulit untuk dihilangkan.

Mekanisme Peristiwa NodeJS

Apa yang saya lakukan saat ini tidak benar-benar optimal tetapi menawarkan saya manfaat yang cukup untuk benar-benar melebihi kontra (Atau jadi saya percaya, jika ada yang peduli untuk memberi saya umpan balik itu bagus). Saya membuat layanan yang membungkus model, katakanlah AuthorService yang memperluas events.EventEmitter dan merupakan fungsi Konstruktor yang kira-kira akan terlihat seperti ini:

function AuthorService() {
    var self = this

    this.create = function() {...}
    this.update = function() {
        ...
        self.emit('AuthorUpdated, before, after)
        ...
    }
}

util.inherits(AuthorService, events.EventEmitter)
module.exports = new AuthorService()

Kelebihannya:

  • Setiap fungsi yang tertarik dapat mendaftar ke Acara Layanan dan diberi tahu. Dengan cara itu, misalnya, ketika Quote diperbarui, AuthorService dapat mendengarkannya dan memperbarui Authors demikian. (Catatan 1)
  • Quote tidak perlu mengetahui semua dokumen yang merujuknya, Layanan hanya memicu QuoteUpdated acara dan semua dokumen yang perlu melakukan operasi saat ini terjadi akan melakukannya.

Catatan 1:Selama layanan ini digunakan kapan pun ada orang yang perlu berinteraksi dengan luwak.

Kekurangannya:

  • Menambahkan kode boilerplate, menggunakan layanan alih-alih luwak secara langsung.
  • Sekarang tidak begitu jelas fungsi apa yang dipanggil saat Anda memicu acara.
  • Anda memisahkan produsen dan konsumen dengan biaya keterbacaan (karena Anda hanya emit('EventName', args) , tidak jelas Layanan mana yang mendengarkan acara ini)

Kerugian lainnya adalah seseorang dapat mengambil Model dari Layanan dan memanggil save() , di mana peristiwa tidak akan dipicu meskipun saya yakin ini dapat diatasi dengan semacam hibrida antara dua solusi ini.

Saya sangat terbuka untuk saran di bidang ini (itulah sebabnya saya memposting pertanyaan ini sejak awal).



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. bagaimana saya bisa memvalidasi kata sandi nama pengguna untuk otentikasi mongodb melalui pymongo?

  2. Skema luwak:Memvalidasi bidang unik, tidak peka huruf besar-kecil

  3. Tidak dapat menggunakan Nested VariableOperators.mapItemsOf di Spring Data MongoDb

  4. Tangani koneksi yang hilang ke mongo db dari nodejs

  5. Bagaimana mencegah banyak dokumen ditambahkan ke database mongodb