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 dariUNION 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.