MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Remova duplicatas ao usar $unionWith no MongoDB


No MongoDB, o $unionWith O estágio de pipeline de agregação realiza uma união de duas coleções e inclui duplicatas.

Isso se comporta de maneira semelhante ao UNION ALL do SQL , que também inclui duplicatas. Por outro lado, usando apenas UNION (ou seja, sem o ALL ) no SQL remove duplicatas.

No MongoDB, não temos a opção de especificar $unionWith ALL ou similar, então precisamos reduzir duplicatas de outra maneira.

No MongoDB, podemos remover duplicatas usando o $group etapa.

Exemplo


Suponha que inserimos os seguintes documentos em duas coleções; um chamado cats e outro chamado 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 suponha que executemos a seguinte consulta para retornar todos os nomes de ambas as coleções:
db.cats.aggregate( [
   { $project: { name: 1, _id: 0 } },
   { $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} }
] ) 

Resultado:
{ "name" :"Fofo" }{ "name" :"Scratch" }{ "name" :"Miau" }{ "name" :"Wag" }{ "name" :"Latido" }{ " name" :"Fofo" }

Podemos ver que o nome Fluffy aparece duas vezes. Isso ocorre porque existem dois Fluffys em nossas coleções – um nos cats coleção e um na coleção dogs coleção.

Isso é bom se estivermos felizes em ter valores duplicados. Mas e se não o fizermos? E se quisermos apenas uma lista de nomes distintos de ambas as coleções?

É aí que o $group palco entra.

Podemos adicionar o $group palco para o name campo, para que fique assim:
db.cats.aggregate( [
   { $project: { name: 1, _id: 0 } },
   { $unionWith: { coll: "dogs", pipeline: [ { $project: { name: 1, _id: 0 } } ]} },
   { $group: { _id: "$name" } }
] ) 

Resultado:
{ "_id" :"Miau" }{ "_id" :"Bark" }{ "_id" :"Scratch" }{ "_id" :"Wag" }{ "_id" :"Fofo" } 
Desta vez, recebemos apenas 5 documentos em vez de 6, e há apenas um Fluffy.