Subdokumen Mongoose vs skema bersarang


122

Saya ingin tahu tentang pro dan kontra penggunaan subdocuments vs lapisan yang lebih dalam di skema utama saya:

var subDoc = new Schema({
  name: String
});

var mainDoc = new Schema({
  names: [subDoc]
});

atau

var mainDoc = new Schema({
  names: [{
    name: String
 }]
});

Saat ini saya menggunakan subdoc di mana-mana tetapi saya terutama bertanya-tanya tentang kinerja atau masalah kueri yang mungkin saya temui.


Saya mencoba mengetikkan jawaban ini kepada Anda, tetapi saya tidak dapat menemukan caranya. Tetapi lihat di sini: mongoosejs.com/docs/subdocs.html
gustavohenke

Berikut adalah tanggapan yang baik tentang pertimbangan MongoDB untuk ditanyakan pada diri Anda sendiri saat membuat skema database Anda: stackoverflow.com/questions/5373198/…
anthonylawson

Maksud Anda, itu juga diperlukan untuk mendeskripsikan _idlapangan? Maksud saya, tidak otomatis jika diaktifkan?
Vadorequest

ada yang tahu kalau _idbidang sub dokumen itu unik? (Dibuat menggunakan cara ke-2 dalam pertanyaan OP)
Saitama

Jawaban:


72

Menurut dokumen , itu persis sama. Namun, menggunakan Skema akan menambahkan _idbidang juga (selama Anda tidak menonaktifkannya), dan mungkin menggunakan lebih banyak sumber daya untuk melacak sub dokumen.

Sintaks deklarasi alternatif

Baru di v3 Jika Anda tidak memerlukan akses ke instance skema sub-dokumen, Anda juga dapat mendeklarasikan sub-dokumen hanya dengan meneruskan literal objek [...]


1
Tapi saya mencoba ini. Mengapa data sub dokumen tidak disimpan dalam koleksi terpisah. Itu selalu disimpan di dalam koleksi mainDoc.
Fizer Khan

17
begitulah cara kerja sub dokumen. mereka menyematkan di dalam dokumen. sebelum bermain dengan luwak, pastikan Anda memahami MongoDB yang mendasarinya.
AndyL

1
Mengenai Skema yang menambahkan _id, itu masuk akal tetapi saya membuat skema dengan array sub-dokumen dan array literal objek dan _id ditambahkan ke keduanya. Apakah perilakunya berubah?
Drew Goodwin

@DrewGoodwin sepertinya sudah seperti ini untuk beberapa saat: stackoverflow.com/questions/17254008/…
cheesemacfly

37

Jika Anda memiliki skema yang digunakan kembali di berbagai bagian model Anda, mungkin berguna untuk menentukan skema individual untuk dokumen anak sehingga Anda tidak perlu menggandakan diri sendiri.


4
Ini jawaban yang bagus. Kadang-kadang saya menggunakan sub dokumen di lebih dari satu model, atau saya memiliki dua bidang dalam model yang perlu dibedakan, tetapi masih memiliki struktur sub dokumen yang sama.
Martin Hallén

2
Anda juga harus mempertimbangkan keuntungan / kerugian dari menyimpan informasi yang berlebihan.
Sam Vloeberghs

25

Anda harus menggunakan dokumen tertanam jika itu adalah dokumen statis atau yang jumlahnya tidak lebih dari beberapa ratus karena pengaruh kinerja. Saya telah membahas tentang masalah itu beberapa waktu yang lalu. Baru-baru ini, Asya Kamsky yang bekerja sebagai arsitek solusi untuk MongoDB telah menulis artikel tentang "menggunakan sub dokumen".

Saya harap itu membantu siapa yang mencari solusi atau praktik terbaik.

Posting asli di http://askasya.com/post/largeembeddedarrays . Anda dapat mencapai profil stackoverflow-nya di https://stackoverflow.com/users/431012/asya-kamsky

Pertama-tama, kita harus mempertimbangkan mengapa kita ingin melakukan hal seperti itu. Biasanya, saya akan menyarankan orang untuk menyematkan hal-hal yang selalu ingin mereka dapatkan kembali ketika mereka mengambil dokumen ini. Sisi lain dari ini adalah Anda tidak ingin menyematkan hal-hal dalam dokumen yang Anda tidak ingin mendapatkannya kembali.

Jika Anda menyematkan aktivitas yang saya lakukan ke dalam dokumen, ini akan bekerja dengan baik pada awalnya karena semua aktivitas saya ada di sana dan dengan sekali membaca Anda bisa mendapatkan kembali semua yang mungkin ingin Anda tunjukkan kepada saya: "Anda baru-baru ini mengeklik ini dan di sini adalah dua komentar terakhir Anda "tetapi apa yang terjadi setelah enam bulan berlalu dan saya tidak peduli dengan hal-hal yang telah saya lakukan beberapa waktu yang lalu dan Anda tidak ingin menunjukkannya kepada saya kecuali jika saya secara khusus mencari aktivitas lama?

Pertama, Anda akhirnya akan mengembalikan dokumen yang lebih besar dan lebih besar dan memperhatikan bagiannya yang semakin kecil. Tetapi Anda dapat menggunakan proyeksi untuk hanya mengembalikan beberapa larik, rasa sakit yang sebenarnya adalah bahwa dokumen pada disk akan menjadi lebih besar dan semuanya akan tetap dibaca meskipun Anda hanya akan mengembalikan sebagian ke pengguna akhir, tetapi karena aktivitas saya tidak akan berhenti selama saya aktif, maka dokumen akan terus berkembang dan berkembang.

Masalah paling jelas dengan ini pada akhirnya Anda akan mencapai batas dokumen 16MB, tetapi itu sama sekali bukan yang harus Anda khawatirkan. Dokumen yang terus berkembang akan menimbulkan biaya yang semakin tinggi setiap kali harus dipindahkan ke disk, dan bahkan jika Anda mengambil langkah untuk mengurangi efek fragmentasi, penulisan Anda secara keseluruhan akan menjadi panjang yang tidak perlu, memengaruhi kinerja keseluruhan aplikasi Anda.

Ada satu hal lagi yang dapat Anda lakukan yang akan benar-benar mematikan kinerja aplikasi Anda dan itu untuk mengindeks larik yang terus meningkat ini. Artinya setiap kali dokumen dengan array ini dipindahkan, jumlah entri indeks yang perlu diperbarui berbanding lurus dengan jumlah nilai yang diindeks dalam dokumen itu, dan semakin besar array, semakin besar angkanya menjadi.

Saya tidak ingin ini membuat Anda takut menggunakan array saat array cocok untuk model data - ini adalah fitur yang kuat dari model data database dokumen, tetapi seperti semua alat canggih, array perlu digunakan dalam keadaan yang tepat dan itu harus digunakan dengan hati-hati.


3
Ini harus menjadi jawaban teratas; itu menghasilkan uang. Buku putih MongoDB sendiri mengatakan hal yang hampir sama.
Jay Edwards

Artikel tentang Pola Bucket ini memuji apa yang Asya bicarakan dengan baik. mongodb.com/blog/post/building-with-patterns-the-bucket-pattern Saya pikir skema subDoc dalam pertanyaan OP akan bekerja dengan baik dengan Pola Bucket.
plong0

13

Pada dasarnya, buat variabel nestedDovdan taruh di sininame: [nestedDov]

Versi Sederhana:

var nestedDoc = new Schema({
  name: String
});

var mainDoc = new Schema({
  names: [nestedDoc]
});

Contoh JSON

{
    "_id" : ObjectId("57c88bf5818e70007dc72e85"),
    "name" : "Corinthia Hotel Budapest",
    "stars" : 5,
    "description" : "The 5-star Corinthia Hotel Budapest on the Grand Boulevard offers free access to its Royal Spa",
    "photos" : [
        "/photos/hotel/corinthiahotelbudapest/1.jpg",
        "/photos/hotel/corinthiahotelbudapest/2.jpg"
    ],
    "currency" : "HUF",
    "rooms" : [
        {
            "type" : "Superior Double or Twin Room",
            "number" : 20,
            "description" : "These are some great rooms",
            "photos" : [
                "/photos/room/corinthiahotelbudapest/2.jpg",
                "/photos/room/corinthiahotelbudapest/5.jpg"
            ],
            "price" : 73000
        },
        {
            "type" : "Deluxe Double Room",
            "number" : 50,
            "description" : "These are amazing rooms",
            "photos" : [
                "/photos/room/corinthiahotelbudapest/4.jpg",
                "/photos/room/corinthiahotelbudapest/6.jpg"
            ],
            "price" : 92000
        },
        {
            "type" : "Executive Double Room",
            "number" : 25,
            "description" : "These are amazing rooms",
            "photos" : [
                "/photos/room/corinthiahotelbudapest/4.jpg",
                "/photos/room/corinthiahotelbudapest/6.jpg"
            ],
            "price" : 112000
        }
    ],
    "reviews" : [
        {
            "name" : "Tamas",
            "id" : "/user/tamas.json",
            "review" : "Great hotel",
            "rating" : 4
        }
    ],
    "services" : [
        "Room service",
        "Airport shuttle (surcharge)",
        "24-hour front desk",
        "Currency exchange",
        "Tour desk"
    ]
}

Contoh:

masukkan deskripsi gambar di sini


1
Itu sama sekali tidak menjawab pertanyaan yang merupakan kinerja.
cyberwombat

Saya telah mengedit sedikit agar lebih masuk akal. Bagaimana menurut anda?
Wayne Chiu

3
Pertanyaannya bukanlah menanyakan bagaimana melakukan skema bersarang. Ini adalah diskusi tentang apakah Mongoose lebih berkinerja dengan skema bersarang atau sub dokumen yang disematkan. Pada dasarnya kita berbicara tentang tolok ukur atau sortir atau kasus tepi di mana Mongoose lebih suka satu sama lain. Dan seperti yang disebutkan jawaban yang dipilih, tampaknya tidak ada bedanya, setidaknya dari V3.
cyberwombat

17
Mungkin tidak bekerja untuk OP, tapi saya menemukan ini sangat membantu. Terima kasih.
Gene Higgins

Ini bagus ketika semua 3 skema dideklarasikan dalam satu file .js, bagaimana kita bisa menanganinya ketika dideklarasikan dalam 3 file .js yang berbeda?
Satyam

9

Saya rasa ini ditangani di tempat lain oleh beberapa pos di SO.

Hanya sedikit:

Kunci besarnya adalah tidak ada jawaban tunggal di sini, hanya serangkaian pertukaran yang agak rumit.


3
Mungkin saya tidak mengutarakan pertanyaan saya dengan benar - Ini bukan pertanyaan tentang bagaimana saya harus menyusun database saya tetapi lebih kepada internal menggunakan subschema vs hanya menulis array di lapisan yang lebih dalam. Penyebab utama saya untuk menggunakan sub skema adalah bahwa saya dapat menggunakan jenis skema kustom dan memvalidasi mereka - sesuatu yang tidak bekerja dengan array bersarang (dari pertanyaan sebelumnya yang saya miliki tentang SO). Sedekat yang saya tahu, subdoc hampir sama dengan array bersarang - saya hanya tidak tahu bagian dalamnya - jika menggunakannya akan menimbulkan masalah kinerja atau semacamnya.
cyberwombat

0

Ada beberapa perbedaan di antara keduanya:

  • Menggunakan skema bersarang berguna untuk validasi.

  • Skema bersarang dapat digunakan kembali di skema lain.

  • Skema bersarang menambahkan bidang '_id' ke sub dokumen kecuali Anda menggunakan "_id: false"
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.