MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Rimuovi i duplicati quando usi $unionWith in MongoDB

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.