I MongoDB er $unionWith
aggregation pipeline stage udfører en forening af to samlinger, og det inkluderer dubletter.
Dette opfører sig på samme måde som SQLs UNION ALL
, som også omfatter dubletter. Derimod bruger du kun UNION
(dvs. uden ALL
)i SQL fjerner dubletter.
I MongoDB har vi ikke mulighed for at angive $unionWith ALL
eller lignende, så vi skal reducere dubletter på en anden måde.
I MongoDB kan vi fjerne dubletter ved at bruge $group
scene.
Eksempel
Antag, at vi indsætter følgende dokumenter i to samlinger; en kaldet cats
og en anden kaldet 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 }
])
Og antag, at vi kører følgende forespørgsel for at returnere alle navne fra begge samlinger:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} }
] )
Resultat:
{ "name" :"Fluffy" }{ "name" :"Scratch" }{ "name" :"Meow" }{ "name" :"Wag" }{ "name" :"Bark" }{ " name" :"Fluffy" }
Vi kan se, at navnet Fluffy optræder to gange. Dette skyldes, at der er to Fluffys i vores samlinger – en i cats
samling og en i dogs
samling.
Dette er fint, hvis vi er glade for at have duplikerede værdier. Men hvad hvis vi ikke gør det? Hvad hvis vi kun vil have en liste over forskellige navne fra begge samlinger?
Det er her $group
scenen kommer ind.
Vi kan tilføje $group
trin til name
felt, så det ser sådan ud:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} },
{ $group: { _id: "$name" } }
] )
Resultat:
{ "_id" :"Meow" }{ "_id" :"Bark" }{ "_id" :"Scratch" }{ "_id" :"Wag" }{ "_id" :"Fluffy" }Denne gang får vi kun 5 dokumenter i stedet for 6, og der er kun én Fluffy.