V MongoDB, $unionWith fáze agregačního potrubí provádí spojení dvou kolekcí a zahrnuje duplikáty.
Chová se podobně jako UNION ALL SQL , která zahrnuje i duplikáty. Naproti tomu pouze pomocí UNION (tj. bez ALL )v SQL odstraňuje duplikáty.
V MongoDB nemáme možnost zadat $unionWith ALL nebo podobně, takže musíme snížit duplikáty jiným způsobem.
V MongoDB můžeme duplikáty odstranit pomocí $group etapa.
Příklad
Předpokládejme, že vložíme následující dokumenty do dvou sbírek; jeden s názvem cats a další s názvem 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 }
]) A předpokládejme, že spustíme následující dotaz, abychom vrátili všechna jména z obou kolekcí:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} }
] ) Výsledek:
{ "name" :"Fluffy" }{ "name" :"Scratch" }{ "name" :"Mňau" }{ "name" :"Wag" }{ "name" :"Bark" }{ " jméno" :"Načechraný" }
Vidíme, že jméno Fluffy se objevuje dvakrát. Je to proto, že v našich kolekcích jsou dva Fluffy – jeden v cats kolekce a jeden v dogs kolekce.
To je v pořádku, pokud jsme rádi, že máme duplicitní hodnoty. Ale co když ne? Co když chceme pouze seznam odlišných jmen z obou kolekcí?
To je místo, kde $group přichází fáze.
Můžeme přidat $group fázi na name pole, takže to vypadá takto:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} },
{ $group: { _id: "$name" } }
] ) Výsledek:
{ "_id" :"Mňau" }{ "_id" :"Štěkat" }{ "_id" :"Škrábnutí" }{ "_id" :"Wag" }{ "_id" :"Načechraný" }
Tentokrát dostáváme pouze 5 dokumentů místo 6 a je tu pouze jeden Fluffy.