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

Cara paling efisien untuk menyimpan kategori bersarang (atau data hierarkis) di Mongo?

Hal pertama yang ingin Anda putuskan adalah jenis pohon apa yang akan Anda gunakan.

Hal besar yang perlu dipertimbangkan adalah data dan pola akses Anda. Anda telah menyatakan bahwa 90% dari semua pekerjaan Anda akan berupa kueri dan pembaruan (e-niaga) hanya akan dijalankan oleh administrator, kemungkinan besar jarang.

Jadi, Anda menginginkan skema yang memberi Anda kekuatan kueri dengan cepat pada anak melalui jalur, yaitu:Olahraga -> Bola Basket -> Pria, Olahraga -> Tenis -> Wanita, dan tidak benar-benar perlu benar-benar menskalakan ke pembaruan.

Seperti yang Anda tunjukkan dengan benar, MongoDB memang memiliki halaman dokumentasi yang bagus untuk ini:https://docs.mongodb.com/manual/applications/data-models-tree-structures/ dimana 10gen benar-benar menyatakan model dan metode skema yang berbeda untuk pohon dan menjelaskan pasang surut utama mereka.

Yang harus menarik perhatian jika Anda ingin melakukan kueri dengan mudah adalah jalur yang terwujud:https://docs.mongodb.com/manual/tutorial/model-tree-structures-with-materialized-paths/

Ini adalah metode yang sangat menarik untuk membangun pohon karena untuk menanyakan contoh yang Anda berikan di atas ke "Wanita" di "Tenis" Anda cukup melakukan regex yang sudah diperbaiki (yang dapat menggunakan indeks:http://docs.mongodb.org/manual/reference/operator/regex/ ) seperti ini:

db.products.find({category: /^Sports,Tennis,Womens[,]/})

untuk menemukan semua produk yang terdaftar di bawah jalur tertentu dari pohon Anda.

Sayangnya model ini sangat buruk dalam memperbarui, jika Anda memindahkan kategori atau mengubah namanya, Anda harus memperbarui semua produk dan mungkin ada ribuan produk di bawah satu kategori.

Metode yang lebih baik adalah dengan menempatkan cat_id pada produk dan kemudian pisahkan kategori menjadi koleksi terpisah dengan skema:

{
    _id: ObjectId(),
    name: 'Women\'s',
    path: 'Sports,Tennis,Womens',
    normed_name: 'all_special_chars_and_spaces_and_case_senstive_letters_taken_out_like_this'
}

Jadi sekarang kueri Anda hanya melibatkan koleksi kategori yang seharusnya membuatnya jauh lebih kecil dan lebih berkinerja. Pengecualian untuk ini adalah saat Anda menghapus kategori, produk masih perlu disentuh.

Jadi contoh mengubah "Tenis" menjadi "Badminton":

db.categories.update({path:/^Sports,Tennis[,]/}).forEach(function(doc){
    doc.path = doc.path.replace(/,Tennis/, ",Badmin");
    db.categories.save(doc);
});

Sayangnya MongoDB tidak menyediakan refleksi dokumen dalam kueri saat ini sehingga Anda harus menariknya keluar dari sisi klien yang sedikit mengganggu, namun mudah-mudahan ini tidak mengakibatkan terlalu banyak kategori yang dibawa kembali.

Dan ini pada dasarnya adalah cara kerjanya. Agak merepotkan untuk memperbarui tetapi kekuatan untuk dapat melakukan kueri secara instan di jalur mana pun menggunakan indeks lebih cocok untuk skenario Anda, saya yakin.

Tentu saja manfaat tambahannya adalah skema ini kompatibel dengan model kumpulan bersarang:http://en.wikipedia .org/wiki/Nested_set_model yang saya temukan berkali-kali sangat bagus untuk situs e-niaga, misalnya, Tenis mungkin berada di bawah "Olahraga" dan "Kenyamanan" dan Anda menginginkan beberapa jalur tergantung dari mana pengguna berasal.

Skema untuk jalur yang terwujud dengan mudah mendukung ini hanya dengan menambahkan path lainnya , sesederhana itu.

Semoga masuk akal, cukup panjang di sana.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Skema Tanggal Luwak

  2. Keamanan MongoDB - Sumber Daya untuk Menjaga Keamanan NoSQL DB

  3. Implementasi pengindeksan internal MongoDB?

  4. JSON dari EJS ke objek JSON di JS

  5. Tidak mungkin membuat pengguna (atau peran berbasis kustom) di Mongo di server NodeJS