Bisakah Anda membagikan pemikiran Anda bagaimana Anda mengimplementasikan versi data dalam MongoDB. (Saya sudah bertanya pertanyaan serupa tentang Cassandra . Jika Anda memiliki pemikiran yang mana db lebih baik untuk itu silakan berbagi)
Misalkan saya perlu membuat catatan versi dalam buku alamat yang sederhana. (Catatan buku alamat disimpan sebagai objek flat json). Saya berharap sejarah:
- akan jarang digunakan
- akan digunakan sekaligus untuk menyajikannya dalam mode "mesin waktu"
- tidak akan ada lebih dari beberapa ratus versi untuk satu catatan. sejarah tidak akan kedaluwarsa.
Saya sedang mempertimbangkan pendekatan berikut:
Buat koleksi objek baru untuk menyimpan sejarah catatan atau perubahan pada catatan. Itu akan menyimpan satu objek per versi dengan referensi ke entri buku alamat. Catatan tersebut akan terlihat sebagai berikut:
{ '_id': 'id baru', 'pengguna': user_id, 'timestamp': timestamp, 'address_book_id': 'id dari catatan buku alamat' 'old_record': {'first_name': 'Jon', 'last_name': 'Doe' ...} }
Pendekatan ini dapat dimodifikasi untuk menyimpan berbagai versi per dokumen. Tapi ini tampaknya pendekatan yang lebih lambat tanpa keuntungan apa pun.
Simpan versi sebagai objek serial (JSON) yang dilampirkan pada entri buku alamat. Saya tidak yakin bagaimana cara melampirkan objek tersebut ke dokumen MongoDB. Mungkin sebagai array string. ( Dimodelkan setelah Versi Dokumen Sederhana dengan CouchDB )
sumber
Jawaban:
Pertanyaan besar pertama ketika terjun ke ini adalah "bagaimana Anda ingin menyimpan perubahan" ?
Pendekatan pribadi saya adalah menyimpan diff. Karena tampilan diff ini benar-benar tindakan khusus, saya akan menempatkan diffs dalam koleksi "sejarah" yang berbeda.
Saya akan menggunakan koleksi yang berbeda untuk menghemat ruang memori. Anda biasanya tidak ingin riwayat lengkap untuk kueri sederhana. Jadi dengan menjaga histori dari objek, Anda juga bisa menyimpannya keluar dari memori yang biasa diakses ketika data itu ditanyakan.
Untuk membuat hidup saya mudah, saya akan membuat dokumen sejarah yang berisi kamus dengan perbedaan waktu. Sesuatu seperti ini:
Untuk membuat hidup saya sangat mudah, saya akan membuat bagian dari DataObjects saya (EntityWrapper, apa pun) yang saya gunakan untuk mengakses data saya. Umumnya objek-objek ini memiliki beberapa bentuk sejarah, sehingga Anda dapat dengan mudah mengganti
save()
metode untuk melakukan perubahan ini pada saat yang sama.UPDATE: 2015-10
Sepertinya sekarang ada spesifikasi untuk menangani JSON diffs . Ini sepertinya cara yang lebih kuat untuk menyimpan diffs / perubahan.
sumber
changes
sangat mudah:db.hist.update({_id: ID}, {$set { changes.12345 : CHANGES } }, true)
Ini akan melakukan upert yang hanya akan mengubah data yang diperlukan. Mongo membuat dokumen dengan "ruang penyangga" untuk menangani jenis perubahan ini. Ia juga menyaksikan bagaimana dokumen dalam koleksi berubah dan memodifikasi ukuran buffer untuk setiap koleksi. Jadi MongoDB dirancang untuk jenis perubahan ini (tambahkan properti baru / push to array).Ada skema versi yang disebut "Vermongo" yang membahas beberapa aspek yang belum ditangani di balasan lain.
Salah satu masalah ini adalah pembaruan bersamaan, yang lain menghapus dokumen.
Vermongo menyimpan salinan dokumen lengkap dalam koleksi bayangan. Untuk beberapa kasus penggunaan, ini mungkin menyebabkan terlalu banyak overhead, tapi saya pikir itu juga menyederhanakan banyak hal.
https://github.com/thiloplanz/v7files/wiki/Vermongo
sumber
Berikut solusi lain menggunakan satu dokumen untuk versi saat ini dan semua versi lama:
data
berisi semua versi. Thedata
array memerintahkan , versi baru hanya akan mendapatkan$push
ed ke akhir array.data.vid
adalah id versi, yang merupakan angka yang bertambah.Dapatkan versi terbaru:
Dapatkan versi spesifik dengan
vid
:Hanya kembalikan bidang yang ditentukan:
Sisipkan versi baru: (dan mencegah penyisipan / pembaruan bersamaan)
2
adalahvid
versi terbaru saat ini dan3
merupakan versi baru yang dimasukkan. Karena Anda memerlukan versi terbaru inivid
, sangat mudah untuk mendapatkan versi berikutnyavid
:nextVID = oldVID + 1
.The
$and
Kondisi akan memastikan, bahwa2
adalah yang terbaruvid
.Dengan cara ini tidak perlu untuk indeks yang unik, tetapi logika aplikasi harus mengurus penambahan
vid
sisipan on.Hapus versi tertentu:
Itu dia!
(ingat 16MB per batas dokumen)
sumber
Jika Anda mencari solusi siap gulung -
Mongoid telah dibangun dalam versi sederhana
http://mongoid.org/en/mongoid/docs/extras.html#versioning
mongoid-history adalah plugin Ruby yang memberikan solusi yang jauh lebih rumit dengan audit, undo dan redo
https://github.com/aq1018/mongoid-history
sumber
Saya mengerjakan solusi ini yang mengakomodasi versi data yang dipublikasikan, konsep, dan historis:
Saya jelaskan model lebih lanjut di sini: http://software.danielwatrous.com/representing-revision-data-in-mongodb/
Bagi yang mungkin menerapkan sesuatu seperti ini di Jawa , berikut ini sebuah contoh:
http://software.danielwatrous.com/using-java-to-work-with-versioned-data/
Termasuk semua kode yang dapat Anda garpu, jika Anda mau
https://github.com/dwatrous/mongodb-revision-objects
sumber
Jika Anda menggunakan luwak, saya telah menemukan plugin berikut untuk menjadi implementasi yang berguna dari format JSON Patch
luwak-tambalan-sejarah
sumber
Pilihan lain adalah menggunakan plugin luwak-sejarah .
sumber
Saya telah menggunakan paket di bawah ini untuk proyek meteor / MongoDB, dan berfungsi dengan baik, keuntungan utama adalah bahwa ia menyimpan sejarah / revisi dalam array dalam dokumen yang sama, karenanya tidak perlu publikasi tambahan atau middleware untuk mengakses perubahan-sejarah . Ini dapat mendukung sejumlah terbatas versi sebelumnya (mis. Sepuluh versi terakhir), juga mendukung perubahan-rangkaian (sehingga semua perubahan yang terjadi dalam periode tertentu akan dicakup oleh satu revisi).
nicklozon / pengumpulan-meteor-revisi
Opsi suara lainnya adalah menggunakan Meteor Vermongo (di sini )
sumber