MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Usuń duplikaty z MongoDB

„dropDups” składnia do tworzenia indeksów została „przestarzała” w MongoDB 2.6 i usunięta w MongoDB 3.0. W większości przypadków używanie tego nie jest dobrym pomysłem, ponieważ „usunięcie” jest arbitralne i każdy „duplikat” może zostać usunięty. Co oznacza, że ​​to, co zostanie „usunięte”, może nie być tym, co naprawdę chcesz usunąć.

W każdym razie napotykasz błąd „długości indeksu”, ponieważ wartość klucza indeksu byłaby dłuższa niż dozwolona. Ogólnie rzecz biorąc, nie masz indeksować 43 pól w żadnej normalnej aplikacji.

Jeśli chcesz usunąć „duplikaty” z kolekcji, najlepszym rozwiązaniem jest uruchomienie zapytania agregującego w celu określenia, które dokumenty zawierają „zduplikowane” dane, a następnie przechodzenie przez tę listę, usuwając „wszystkie oprócz jednego” z już „unikalnych” _id wartości z kolekcji docelowej. Można to zrobić za pomocą operacji zbiorczych, aby uzyskać maksymalną wydajność.

UWAGA :Trudno mi uwierzyć, że twoje dokumenty faktycznie zawierają 43 "unikalne" pola. Prawdopodobnie „wszystko, czego potrzebujesz” jest po prostu zidentyfikować tylko te pola, które sprawiają, że dokument jest „unikatowy”, a następnie postępuj zgodnie z procesem opisanym poniżej:

var bulk = db.testkdd.initializeOrderedBulkOp(),
    count = 0;

// List "all" fields that make a document "unique" in the `_id`
// I am only listing some for example purposes to follow
db.testkdd.aggregate([
    { "$group": {
        "_id": {
           "duration" : "$duration",
          "protocol_type": "$protocol_type", 
          "service": "$service",
          "flag": "$flag"
        },
        "ids": { "$push": "$_id" },
        "count": { "$sum": 1 }
    }},
    { "$match": { "count": { "$gt": 1 } } }
],{ "allowDiskUse": true}).forEach(function(doc) {
    doc.ids.shift();     // remove first match
    bulk.find({ "_id": { "$in": doc.ids } }).remove();  // removes all $in list
    count++;

    // Execute 1 in 1000 and re-init
    if ( count % 1000 == 0 ) {
       bulk.execute();
       bulk = db.testkdd.initializeOrderedBulkOp();
    }
});

if ( count % 1000 != 0 ) 
    bulk.execute();

Jeśli masz wersję MongoDB „niższą” niż 2.6 i nie masz operacji zbiorczych, możesz spróbować ze standardowym .remove() wewnątrz pętli. Zauważając również, że .aggregate() nie zwróci tutaj kursora, a pętla musi zmienić się na:

db.testkdd.aggregate([
   // pipeline as above
]).result.forEach(function(doc) {
    doc.ids.shift();  
    db.testkdd.remove({ "_id": { "$in": doc.ids } });
});

Ale pamiętaj, aby dokładnie przyjrzeć się swoim dokumentom i uwzględnić tylko „tylko” „unikalne” pola, które mają być częścią grupowania _id . W przeciwnym razie niczego nie usuniesz, ponieważ nie ma tam duplikatów.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Zestawy replik MongoDB z arbitrami

  2. Usuń obiekt z tablicy zagnieżdżonej za pomocą $pull i $[identyfikator] (mongoDB 3.6)

  3. Grupuj według wartości i warunków

  4. Bitwa o bazy danych NoSQL — porównanie MongoDB i Oracle NoSQL

  5. Django-nonrel vs Django-mongodb vs Mongokit vs pymongo native