sql >> Base de Datos >  >> NoSQL >> MongoDB

Eliminar duplicados al usar $ unionWith en MongoDB

En MongoDB, el $unionWith La etapa de canalización de agregación realiza una unión de dos colecciones e incluye duplicados.

Esto se comporta de manera similar a UNION ALL de SQL , que también incluye duplicados. Por el contrario, usando solo UNION (es decir, sin ALL )en SQL elimina los duplicados.

En MongoDB, no tenemos la opción de especificar $unionWith ALL o similar, por lo que debemos reducir los duplicados de otra manera.

En MongoDB, podemos eliminar duplicados usando el $group escenario.

Ejemplo

Supongamos que insertamos los siguientes documentos en dos colecciones; uno llamado cats y otro llamado 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 }
    ])

Y supongamos que ejecutamos la siguiente consulta para devolver todos los nombres de ambas colecciones:

db.cats.aggregate( [
   { $project: { name: 1, _id: 0 } },
   { $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} }
] )

Resultado:

{ "name" : "Fluffy" }
{ "name" : "Scratch" }
{ "name" : "Meow" }
{ "name" : "Wag" }
{ "name" : "Bark" }
{ "name" : "Fluffy" }

Podemos ver que el nombre Fluffy aparece dos veces. Esto se debe a que hay dos Fluffys en nuestras colecciones:uno en los cats colección y uno en los dogs colección.

Esto está bien si estamos felices de tener valores duplicados. Pero, ¿y si no lo hacemos? ¿Qué pasa si solo queremos una lista de nombres distintos de ambas colecciones?

Ahí es donde el $group llega el escenario.

Podemos agregar el $group etapa al name campo, para que se vea así:

db.cats.aggregate( [
   { $project: { name: 1, _id: 0 } },
   { $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} },
   { $group: { _id: "$name" } }
] )

Resultado:

{ "_id" : "Meow" }
{ "_id" : "Bark" }
{ "_id" : "Scratch" }
{ "_id" : "Wag" }
{ "_id" : "Fluffy" }

Esta vez solo tenemos 5 documentos en lugar de 6, y solo hay un Fluffy.