Bagaimana saya melakukan yang setara SQL Join di MongoDB?
Misalnya, Anda memiliki dua koleksi (pengguna dan komentar) dan saya ingin menarik semua komentar dengan pid = 444 bersama dengan info pengguna untuk masing-masing.
comments
{ uid:12345, pid:444, comment="blah" }
{ uid:12345, pid:888, comment="asdf" }
{ uid:99999, pid:444, comment="qwer" }
users
{ uid:12345, name:"john" }
{ uid:99999, name:"mia" }
Apakah ada cara untuk menarik semua komentar dengan bidang tertentu (mis. ... find ({pid: 444})) dan informasi pengguna yang terkait dengan setiap komentar dalam sekali jalan?
Saat ini, saya pertama-tama mendapatkan komentar yang sesuai dengan kriteria saya, kemudian mencari tahu semua uid di set hasil itu, mendapatkan objek pengguna, dan menggabungkannya dengan hasil komentar. Sepertinya saya salah melakukannya.
Jawaban:
Pada Mongo 3.2 jawaban untuk pertanyaan ini sebagian besar tidak lagi benar. Operator $ lookup baru yang ditambahkan ke pipa agregasi pada dasarnya identik dengan gabungan luar kiri:
https://docs.mongodb.org/master/reference/operator/aggregation/lookup/#pipe._S_lookup
Dari dokumen:
Tentu saja Mongo bukan database relasional, dan para pengembang sedang berhati-hati untuk merekomendasikan kasus penggunaan khusus untuk $ lookup, tetapi setidaknya pada 3.2 melakukan join sekarang dimungkinkan dengan MongoDB.
sumber
Halaman ini di situs mongodb resmi menjawab persis pertanyaan ini:
https://mongodb-documentation.readthedocs.io/en/latest/ecosystem/tutorial/model-data-for-ruby-on-rails.html
sumber
Kami dapat menggabungkan / menggabungkan semua data hanya dalam satu koleksi dengan fungsi yang mudah dalam beberapa baris menggunakan konsol klien mongodb, dan sekarang kami dapat dapat melakukan permintaan yang diinginkan. Di bawah contoh lengkap,
.- Penulis:
.- Kategori:
.- Buku
.- Peminjaman buku
.- Sihir:
.- Dapatkan data pengumpulan baru:
.- Respon :)
Saya harap kalimat ini dapat membantu Anda.
sumber
Anda harus melakukannya dengan cara yang Anda gambarkan. MongoDB adalah basis data non-relasional dan tidak mendukung gabungan.
sumber
Seperti yang orang lain tunjukkan, Anda mencoba membuat database relasional dari tidak ada database relasional yang sebenarnya tidak ingin Anda lakukan selain itu, jika Anda memiliki kasus yang harus Anda lakukan di sini, ini adalah solusi yang dapat Anda gunakan. Kami pertama-tama melakukan pencarian foreach pada koleksi A (atau dalam kasus pengguna Anda) dan kemudian kami mendapatkan setiap item sebagai objek kemudian kami menggunakan properti objek (dalam kasus Anda) untuk mencari dalam koleksi kedua kami (dalam komentar kasus Anda) jika kami dapat menemukannya maka kami memiliki kecocokan dan kami dapat mencetak atau melakukan sesuatu dengannya. Semoga ini bisa membantu Anda dan semoga berhasil :)
sumber
Dengan kombinasi yang tepat dari $ lookup , $ project dan $ match , Anda dapat bergabung dengan tabel mutiple pada beberapa parameter. Ini karena mereka dapat dirantai beberapa kali.
Misalkan kita ingin melakukan hal berikut ( referensi )
Langkah 1: Tautkan semua tabel
Anda dapat $ mencari tabel sebanyak yang Anda inginkan.
$ lookup - satu untuk setiap tabel dalam kueri
$ melepas - karena data dinormalisasi dengan benar, kalau tidak dibungkus dalam array
Kode python ..
Langkah 2: Tentukan semua persyaratan
$ proyek : tentukan semua pernyataan kondisional di sini, ditambah semua variabel yang ingin Anda pilih.
Kode Python ..
Langkah 3: Bergabunglah dengan semua persyaratan
$ match - gabung semua ketentuan menggunakan ATAU DAN DAN dll. Ada beberapa hal berikut.
$ project : batalkan semua persyaratan
Kode Python ..
Kombinasi tabel, kondisional, dan gabungan dapat dilakukan dengan cara ini.
sumber
Berikut ini contoh koleksi "gabungan" * Aktor dan Film :
https://github.com/mongodb/cookbook/blob/master/content/patterns/pivot.txt
Itu menggunakan
.mapReduce()
metode* bergabung - alternatif untuk bergabung dalam basis data berorientasi dokumen
sumber
Anda dapat bergabung dengan dua koleksi di Mongo dengan menggunakan pencarian yang ditawarkan dalam versi 3.2. Dalam kasus Anda, kueri akan menjadi
atau Anda juga dapat bergabung sehubungan dengan pengguna maka akan ada sedikit perubahan seperti yang diberikan di bawah ini.
Ini akan berfungsi sama seperti bergabung kiri dan kanan dalam SQL.
sumber
Itu tergantung pada apa yang Anda coba lakukan.
Anda saat ini mengaturnya sebagai database yang dinormalisasi, yang baik-baik saja, dan cara Anda melakukannya sesuai.
Namun, ada cara lain untuk melakukannya.
Anda bisa memiliki koleksi posting yang telah menanamkan komentar untuk setiap posting dengan referensi ke pengguna yang Anda bisa dapatkan secara iteratif. Anda dapat menyimpan nama pengguna dengan komentar, Anda dapat menyimpan semuanya dalam satu dokumen.
Masalahnya dengan NoSQL adalah dirancang untuk skema fleksibel dan membaca dan menulis yang sangat cepat. Dalam sebuah peternakan Big Data khas, basis data adalah hambatan terbesar, Anda memiliki lebih sedikit mesin basis data daripada aplikasi dan server ujung depan ... mereka lebih mahal tetapi lebih kuat, juga ruang hard drive relatif murah. Normalisasi datang dari konsep mencoba menghemat ruang, tetapi ia datang dengan biaya untuk membuat database Anda berkinerja rumit. Bergabung dan memverifikasi integritas hubungan, melakukan operasi kaskade. Semua yang menyimpan sakit kepala pengembang jika mereka mendesain database dengan benar.
Dengan NoSQL, jika Anda menerima bahwa redundansi dan ruang penyimpanan tidak menjadi masalah karena biayanya (baik dalam waktu prosesor yang diperlukan untuk melakukan pembaruan dan biaya hard drive untuk menyimpan data tambahan), denormalisasi bukan merupakan masalah (untuk array tertanam yang menjadi ratusan ribu item itu bisa menjadi masalah kinerja, tetapi sebagian besar waktu itu bukan masalah). Selain itu, Anda akan memiliki beberapa aplikasi dan server ujung depan untuk setiap cluster basis data. Mintalah mereka melakukan angkat berat dari gabungan dan biarkan server database tetap membaca dan menulis.
TL; DR: Apa yang Anda lakukan baik-baik saja, dan ada cara lain untuk melakukannya. Lihat pola model data dokumentasi mongodb untuk beberapa contoh hebat. http://docs.mongodb.org/manual/data-modeling/
sumber
Ada spesifikasi yang didukung banyak driver yang disebut DBRef.
Diambil dari Dokumentasi MongoDB: Model Data> Referensi Model Data> Referensi Database
sumber
$ lookup (agregasi)
Melakukan gabungan luar kiri ke koleksi yang tidak di-shard di database yang sama untuk memfilter dalam dokumen dari koleksi "bergabung" untuk diproses. Untuk setiap dokumen input, tahap $ lookup menambahkan bidang array baru yang unsur-unsurnya adalah dokumen yang cocok dari koleksi "bergabung". Tahap $ lookup melewati dokumen-dokumen yang dibentuk kembali ini ke tahap berikutnya. Tahap $ lookup memiliki sintaks berikut:
Pencocokan Kesetaraan
Untuk melakukan kecocokan kesetaraan antara bidang dari dokumen input dengan bidang dari dokumen koleksi "gabungan", tahap $ lookup memiliki sintaks berikut:
Operasi akan sesuai dengan pernyataan pseudo-SQL berikut:
URL Mongo
sumber
Sebelum 3.2.6 , Mongodb tidak mendukung permintaan bergabung seperti mysql. solusi di bawah ini yang bekerja untuk Anda.
sumber
Anda dapat menjalankan query SQL termasuk bergabung di MongoDB dengan mongo_fdw dari Postgres.
sumber
MongoDB tidak mengizinkan bergabung, tetapi Anda bisa menggunakan plugin untuk mengatasinya. Periksa plugin mongo-gabung. Ini yang terbaik dan saya sudah menggunakannya. Anda dapat menginstalnya menggunakan npm secara langsung seperti ini
npm install mongo-join
. Anda dapat melihat dokumentasi lengkapnya dengan contoh .(++) alat yang sangat membantu ketika kita perlu bergabung (N) koleksi
(-) kami dapat menerapkan kondisi hanya pada tingkat atas permintaan
Contoh
sumber
Anda dapat melakukannya menggunakan pipa agregasi, tetapi sulit untuk menulisnya sendiri.
Anda dapat menggunakan
mongo-join-query
untuk membuat pipa agregasi secara otomatis dari permintaan Anda.Seperti inilah tampilan kueri Anda:
Hasil Anda akan memiliki objek pengguna di
uid
bidang dan Anda dapat menautkan level sedalam yang Anda inginkan. Anda dapat mengisi referensi ke pengguna, yang membuat referensi ke Tim, yang membuat referensi ke sesuatu yang lain, dll.Penafian : Saya menulis
mongo-join-query
untuk mengatasi masalah ini.sumber
playORM dapat melakukannya untuk Anda menggunakan S-SQL (Scalable SQL) yang hanya menambahkan partisi sehingga Anda dapat melakukan penggabungan di dalam partisi.
sumber
Tidak, sepertinya Anda tidak melakukan kesalahan. Gabungan MongoDB adalah "sisi klien". Seperti yang Anda katakan:
Ini bukan "nyata" bergabung, tapi itu sebenarnya jauh lebih berguna daripada SQL bergabung karena Anda tidak harus berurusan dengan baris duplikat untuk "banyak" bergabung dengan sisi, sebagai gantinya Anda menghias set yang dipilih sebelumnya.
Ada banyak omong kosong dan FUD di halaman ini. Ternyata 5 tahun kemudian MongoDB masih menjadi masalah.
sumber
Saya pikir, jika Anda memerlukan tabel data yang dinormalisasi - Anda perlu mencoba beberapa solusi database lainnya.
Tapi saya sudah menyelesaikan solusi untuk MOngo di Git By the way, dalam kode sisipan - ia memiliki nama film, tetapi ID film noi .
Masalah
Anda memiliki koleksi Aktor dengan berbagai Film yang telah mereka lakukan.
Anda ingin menghasilkan koleksi Film dengan berbagai Aktor di masing-masing.
Beberapa sampel data
Larutan
Kita perlu mengulang setiap film dalam dokumen Aktor dan memancarkan setiap Film satu per satu.
Tangkapan di sini sedang dalam fase reduksi. Kami tidak dapat memancarkan array dari fase pengurangan, jadi kami harus membuat array Aktor di dalam dokumen "nilai" yang dikembalikan.
KodePerhatikan bagaimana actor_list sebenarnya adalah objek javascript yang berisi larik. Perhatikan juga bahwa peta memancarkan struktur yang sama.
Jalankan yang berikut ini untuk menjalankan peta / kurangi, tampilkan ke koleksi "pivot" dan cetak hasilnya:
printjson (db.actors.mapReduce (peta, kurangi, "pivot")); db.pivot.find (). forEach (printjson);
Berikut adalah contoh output, perhatikan bahwa "Pretty Woman" dan "Runaway Bride" memiliki "Richard Gere" dan "Julia Roberts".
sumber
Kami dapat menggabungkan dua koleksi dengan menggunakan kueri mongoDB. Berikut ini contohnya, Komentar -
Userss--
Sub-permintaan MongoDB untuk JOIN--
Dapatkan hasil dari Collection-- yang baru dibuat
Hasil--
Semoga ini bisa membantu.
sumber