W MongoDB $unionWith
Etap potoku agregacji łączy dwie kolekcje i zawiera duplikaty.
Zachowuje się to podobnie do UNION ALL
w SQL , który obejmuje również duplikaty. W przeciwieństwie do tego, używając tylko UNION
(tj. bez ALL
)w SQL usuwa duplikaty.
W MongoDB nie mamy możliwości określenia $unionWith ALL
lub podobne, więc musimy zmniejszyć liczbę duplikatów w inny sposób.
W MongoDB możemy usunąć duplikaty za pomocą $group
scena.
Przykład
Załóżmy, że wstawiamy następujące dokumenty do dwóch zbiorów; jeden o nazwie cats
i inny o nazwie dogs
:
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 }
])
I załóżmy, że uruchamiamy następujące zapytanie, aby zwrócić wszystkie nazwy z obu kolekcji:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} }
] )
Wynik:
{ "name" : "Fluffy" } { "name" : "Scratch" } { "name" : "Meow" } { "name" : "Wag" } { "name" : "Bark" } { "name" : "Fluffy" }
Widzimy, że nazwa Fluffy pojawia się dwukrotnie. Dzieje się tak, ponieważ w naszych kolekcjach znajdują się dwa puchacze – jeden w katalogu cats
kolekcja i jeden w dogs
kolekcja.
Jest to w porządku, jeśli cieszymy się, że mamy zduplikowane wartości. Ale co, jeśli tego nie zrobimy? Co jeśli chcemy tylko listę różnych nazw z obu kolekcji?
To tam $group
wchodzi scena.
Możemy dodać $group
etap do name
tak, aby wyglądało to tak:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} },
{ $group: { _id: "$name" } }
] )
Wynik:
{ "_id" : "Meow" } { "_id" : "Bark" } { "_id" : "Scratch" } { "_id" : "Wag" } { "_id" : "Fluffy" }
Tym razem otrzymujemy tylko 5 dokumentów zamiast 6 i jest tylko jeden Fluffy.