Trova record duplicati in MongoDB


116

Come troverei i campi duplicati in una raccolta di mongo.

Vorrei controllare se qualcuno dei campi "nome" è duplicato.

{
    "name" : "ksqn291",
    "__v" : 0,
    "_id" : ObjectId("540f346c3e7fc1054ffa7086"),
    "channel" : "Sales"
}

Grazie molto!


5
Il flag duplicato per questa domanda è immeritato. Questa domanda chiede come trovare record duplicati, non come prevenirli.
Harry King

Risposte:


210

Utilizzare l'aggregazione su namee ottenere namecon count > 1:

db.collection.aggregate(
    {"$group" : { "_id": "$name", "count": { "$sum": 1 } } },
    {"$match": {"_id" :{ "$ne" : null } , "count" : {"$gt": 1} } }, 
    {"$project": {"name" : "$_id", "_id" : 0} }
)

Per ordinare i risultati dal numero maggiore al numero minimo di duplicati:

db.collection.aggregate(
    {"$group" : { "_id": "$name", "count": { "$sum": 1 } } },
    {"$match": {"_id" :{ "$ne" : null } , "count" : {"$gt": 1} } }, 
    {"$sort": {"count" : -1} },
    {"$project": {"name" : "$_id", "_id" : 0} }     
)

Per utilizzarlo con un nome di colonna diverso da "nome", cambia " $ nome " in " $ nome_colonna "


1
"$match": {"_id" :{ "$ne" : null } - non è necessario qui, poiché la seconda parte dell'istruzione basterebbe filtrare il risultato. Quindi count > 1andrà bene solo il controllo del gruppo che ha avuto .
BatScream

5
Tks @BatScream. {"$ ne": null} è presente solo nel caso in cui 'nome' è nullo o non esiste. Anche l'aggregazione sarà considerata nulla.
anhlc

1
Benvenuto. Ma allora perché controllare il _idcampo. È sempre garantito che non sarà nullo dopo l' groupoperazione.
BatScream

4
Il valore _iddi un documento da uno $groupstage può essere nullo.
wdberkeley

1
Quale sarà l'output di questo? Se corro ottengo tutti i documenti di cui ho bisogno è che voglio solo gli ID / nomi duplicati.
Kannan T

24

È possibile trovare la listdi duplicatenomi utilizzando la seguente aggregatecondotta:

  • Grouptutti i record hanno simili name.
  • Matchquelli groupscon record maggiori di 1.
  • Poi di groupnuovo a projecttutti i nomi duplicati come file array.

Il codice:

db.collection.aggregate([
{$group:{"_id":"$name","name":{$first:"$name"},"count":{$sum:1}}},
{$match:{"count":{$gt:1}}},
{$project:{"name":1,"_id":0}},
{$group:{"_id":null,"duplicateNames":{$push:"$name"}}},
{$project:{"_id":0,"duplicateNames":1}}
])

operazione:

{ "duplicateNames" : [ "ksqn291", "ksqn29123213Test" ] }

10

La risposta anhic data può essere molto inefficiente se si dispone di un database di grandi dimensioni e il nome dell'attributo è presente solo in alcuni documenti.

Per migliorare l'efficienza è possibile aggiungere una corrispondenza $ all'aggregazione.

db.collection.aggregate(
    {"$match": {"name" :{ "$ne" : null } } }, 
    {"$group" : {"_id": "$name", "count": { "$sum": 1 } } },
    {"$match": {"count" : {"$gt": 1} } }, 
    {"$project": {"name" : "$_id", "_id" : 0} }
)

3
db.getCollection('orders').aggregate([  
    {$group: { 
            _id: {name: "$name"},
            uniqueIds: {$addToSet: "$_id"},
            count: {$sum: 1}
        } 
    },
    {$match: { 
        count: {"$gt": 1}
        }
    }
])

Primo gruppo Interroga il gruppo in base ai campi.

Quindi controlliamo l'ID univoco e lo contiamo, se count è maggiore di 1, il campo è duplicato nell'intera raccolta in modo che l'oggetto venga gestito dalla query $ match.


1
non sono riuscito a far funzionare anche questo per me. Giù il voto!
Mathieu G

Questo post è vecchio ma potrebbe aiutare qualcuno. controlla questo, controllerò nel mio locale che funzioni. Anche io mi sono imbattuto in un blog riguardo a questo. Per favore guarda. compose.com/articles/finding-duplicate-documents-in-mongodb
Aman shrivastava

Sono riuscito a farlo funzionare - modificato per aggiornare alla versione funzionante confermata.
AL Strine
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.