In MongoDB, de $unionWith
aggregatie-pijplijnfase voert een samenvoeging uit van twee collecties en bevat duplicaten.
Dit gedraagt zich op dezelfde manier als SQL's UNION ALL
, die ook duplicaten omvat. Daarentegen, met alleen UNION
(d.w.z. zonder de ALL
)in SQL verwijdert duplicaten.
In MongoDB hebben we niet de mogelijkheid om $unionWith ALL
op te geven of iets dergelijks, dus we moeten duplicaten op een andere manier verminderen.
In MongoDB kunnen we duplicaten verwijderen met behulp van de $group
fase.
Voorbeeld
Stel dat we de volgende documenten invoegen in twee verzamelingen; een genaamd cats
en een andere genaamd 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 }
])
En stel dat we de volgende query uitvoeren om alle namen van beide verzamelingen te retourneren:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} }
] )
Resultaat:
{ "name" : "Fluffy" } { "name" : "Scratch" } { "name" : "Meow" } { "name" : "Wag" } { "name" : "Bark" } { "name" : "Fluffy" }
We kunnen zien dat de naam Fluffy twee keer voorkomt. Dit komt omdat er twee Fluffy's in onze collecties zijn - één in de cats
collectie en één in de dogs
collectie.
Dit is prima als we graag dubbele waarden hebben. Maar wat als we dat niet doen? Wat als we alleen een lijst met verschillende namen uit beide collecties willen?
Dat is waar de $group
fase komt binnen.
We kunnen de $group
. toevoegen stap naar de name
veld, zodat het er als volgt uitziet:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} },
{ $group: { _id: "$name" } }
] )
Resultaat:
{ "_id" : "Meow" } { "_id" : "Bark" } { "_id" : "Scratch" } { "_id" : "Wag" } { "_id" : "Fluffy" }
Deze keer krijgen we maar 5 documenten in plaats van 6, en er is maar één Fluffy.