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.