In MongoDB, il $unionWith
la fase della pipeline di aggregazione esegue un'unione di due raccolte e include duplicati.
Questo si comporta in modo simile a UNION ALL
di SQL , che include anche i duplicati. Al contrario, usando solo UNION
(cioè senza il ALL
)in SQL rimuove i duplicati.
In MongoDB, non abbiamo la possibilità di specificare $unionWith ALL
o simili, quindi dobbiamo ridurre i duplicati in un altro modo.
In MongoDB, possiamo rimuovere i duplicati usando il $group
fase.
Esempio
Supponiamo di inserire i seguenti documenti in due raccolte; uno chiamato cats
e un altro chiamato 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 }
])
E supponiamo di eseguire la seguente query per restituire tutti i nomi di entrambe le raccolte:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} }
] )
Risultato:
{ "name" : "Fluffy" } { "name" : "Scratch" } { "name" : "Meow" } { "name" : "Wag" } { "name" : "Bark" } { "name" : "Fluffy" }
Possiamo vedere che il nome Fluffy appare due volte. Questo perché ci sono due Fluffy nelle nostre collezioni:uno nei cats
collezione e uno nei dogs
raccolta.
Questo va bene se siamo felici di avere valori duplicati. Ma cosa succede se non lo facciamo? E se volessimo solo un elenco di nomi distinti da entrambe le raccolte?
Ecco dove si trova il $group
entra in scena.
Possiamo aggiungere il $group
fase al name
campo, in modo che assomigli a questo:
db.cats.aggregate( [
{ $project: { name: 1, _id: 0 } },
{ $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} },
{ $group: { _id: "$name" } }
] )
Risultato:
{ "_id" : "Meow" } { "_id" : "Bark" } { "_id" : "Scratch" } { "_id" : "Wag" } { "_id" : "Fluffy" }
Questa volta riceviamo solo 5 documenti invece di 6, e c'è solo un Fluffy.