Jika Anda terbiasa dengan SQL, Anda mungkin tahu tentang UNION klausa, yang menggabungkan hasil dari dua kueri menjadi satu set hasil. Khususnya, UNION ALL termasuk duplikat.
Di MongoDB, kita dapat menggunakan $unionWith tahap pipa agregasi untuk mencapai efek yang sama dengan UNION ALL menghasilkan. $unionWith stage melakukan penyatuan dua koleksi – ini menggabungkan hasil pipa dari dua koleksi menjadi satu set hasil. Dan itu termasuk duplikat.
Contoh
Misalkan kita membuat dua koleksi; yang disebut cats dan yang lain disebut dogs . Dan kami memasukkan dokumen berikut ke dalamnya:
db.cats.insertMany([
{ _id: 1, name: "Fluffy", type: "Cat", weight: 5 },
{ _id: 2, name: "Scratch", type: "Cat", weight: 3 },
{ _id: 3, name: "Meow", type: "Cat", weight: 7 }
])
db.dogs.insertMany([
{ _id: 1, name: "Wag", type: "Dog", weight: 20 },
{ _id: 2, name: "Bark", type: "Dog", weight: 10 },
{ _id: 3, name: "Fluffy", type: "Dog", weight: 40 }
])
Kami sekarang dapat menjalankan kueri terhadap koleksi tersebut dan menggunakan $unionWith tahap untuk menggabungkan hasil setiap kueri.
Contoh:
db.cats.aggregate( [
{ $set: { _id: "$_id" } },
{ $unionWith: { coll: "dogs", pipeline: [ { $set: { _id: "$_id" } } ] } },
{ $sort: { type: 1, weight: -1, name: 1 } }
] ) Hasil:
{ "_id" :3, "name" :"Meow", "type" :"Cat", "weight" :7 }{ "_id" :1, "name" :"Fluffy", "type" :"Cat", "weight" :5 }{ "_id" :2, "name" :"Scratch", "type" :"Cat", "weight" :3 }{ "_id" :3, "name" :"Fluffy", "type" :"Anjing", "berat" :40 }{ "_id" :1, "name" :"Wag", "type" :"Anjing", "berat" :20 }{ " _id" :2, "name" :"Bark", "type" :"Anjing", "berat" :10 }
Dalam contoh ini, setiap dokumen memiliki bidang jenis dengan salah satu cat atau dogs sehingga cukup jelas dokumen mana yang berasal dari koleksi mana.
Tetapi jika dokumen tidak memiliki bidang tipe, maka akan lebih sulit untuk menentukan di mana satu koleksi selesai dan koleksi lainnya dimulai. Dalam hal ini, kita dapat menggunakan string literal di $set panggung untuk mewakili nama koleksi.
Contoh:
db.cats.aggregate( [
{ $set: { _id: "cat" } },
{ $unionWith: { coll: "dogs", pipeline: [ { $set: { _id: "dog" } } ] } },
{ $sort: { type: 1, weight: -1, name: 1 } }
] ) Hasil:
{ "_id" :"cat", "name" :"Meow", "type" :"Cat", "weight" :7 }{ "_id" :"cat", "name" :"Fluffy" , "type" :"Cat", "weight" :5 }{ "_id" :"cat", "name" :"Scratch", "type" :"Cat", "weight" :3 }{ "_id" :"anjing", "nama" :"Fluffy", "type" :"Dog", "weight" :40 }{ "_id" :"dog", "name" :"Wag", "type" :"Anjing ", "berat" :20 }{ "_id" :"anjing", "nama" :"Kulit", "jenis" :"Anjing", "berat" :10 } Mengurutkan di Seluruh Koleksi
Pada contoh sebelumnya, kucing dan anjing disortir sedemikian rupa sehingga memisahkan mereka menjadi dua kelompok yang berbeda; kucing dulu, baru anjing. Ini terjadi terutama karena kami mengurutkan berdasarkan type lapangan terlebih dahulu.
Tapi kita bisa menyortirnya di bidang lain, yang bisa mengakibatkan kucing dan anjing digabungkan.
Contoh:
db.cats.aggregate( [
{ $set: { _id: "cat" } },
{ $unionWith: { coll: "dogs", pipeline: [ { $set: { _id: "dog" } } ] } },
{ $sort: { name: 1 } }
] ) Hasil:
{ "_id" :"anjing", "name" :"Bark", "type" :"Anjing", "berat" :10 }{ "_id" :"cat", "name" :"Fluffy" , "type" :"Cat", "weight" :5 }{ "_id" :"dog", "name" :"Fluffy", "type" :"Dog", "weight" :40 }{ "_id" :"cat", "name" :"Meow", "type" :"Cat", "weight" :7 }{ "_id" :"cat", "name" :"Scratch", "type" :"Cat ", "berat" :3 }{ "_id" :"anjing", "nama" :"Wag", "type" :"Anjing", "berat" :20 } Proyeksi
Anda dapat menggunakan $project tahap untuk menentukan bidang mana yang akan diteruskan ke tahap berikutnya dalam pipa. Misalnya, Anda dapat mengurangi jumlah bidang yang dikembalikan oleh kueri.
Contoh:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} }
] ) Hasil:
{ "name" :"Fluffy" }{ "name" :"Scratch" }{ "name" :"Meow" }{ "name" :"Wag" }{ "name" :"Bark" }{ " name" :"Fluffy" } Hapus Duplikat
Anda dapat menggunakan $group tahap untuk menghilangkan duplikat yang berlebihan dari hasil.
Misalnya, kueri sebelumnya mengembalikan dua hewan peliharaan bernama Fluffy. Kita dapat menambahkan $group tahap ke kueri itu untuk menghilangkan duplikat yang berlebihan, sehingga hanya satu Fluffy yang dikembalikan.
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} },
{ $group: { _id: "$name" } }
] ) Hasil:
{ "_id" :"Meow" }{ "_id" :"Bark" }{ "_id" :"Scratch" }{ "_id" :"Wag" }{ "_id" :"Fluffy" }
Kali ini, hanya satu Fluffy yang dikembalikan.
Kolom Tidak Cocok
Salah satu keuntungan dari $unionWith MongoDB memiliki lebih dari UNION ALL SQL adalah dapat digunakan dengan kolom yang tidak cocok.
SQL UNION klausa mensyaratkan bahwa:
- Kedua kueri mengembalikan jumlah kolom yang sama
- Kolom dalam urutan yang sama
- Kolom yang cocok harus dari tipe data yang kompatibel
MongoDB $unionWith panggung tidak memaksakan batasan ini.
Oleh karena itu, kita dapat menggunakan $unionWith untuk melakukan sesuatu seperti ini:
db.cats.aggregate( [
{ $set: { _id: "$_id" } },
{ $unionWith: { coll: "employees", pipeline: [ { $set: { _id: "$_id" } } ] } },
{ $sort: { type: 1, salary: -1 } }
] ) Hasil:
{ "_id" :2, "name" :"Sarah", "salary" :128000 }{ "_id" :5, "name" :"Beck", "salary" :82000 }{ "_id" :4, "nama" :"Chris", "gaji" :45000 }{ "_id" :3, "name" :"Fritz", "gaji" :25000 }{ "_id" :1, "name" :"Fluffy ", "type" :"Cat", "weight" :5 }{ "_id" :2, "name" :"Scratch", "type" :"Cat", "weight" :3 }{ "_id" :3, "name" :"Meow", "type" :"Cat", "weight" :7 }
Dalam hal ini, kami bergabung dengan cats koleksi dengan employees koleksi. employees koleksi tidak memiliki bidang yang sama dengan cats koleksi, tapi tidak apa-apa – masih berfungsi.