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

Usuń duplikaty na mongodb

jeśli jesteś przygotowany na po prostu odrzucenie wszystkich innych duplikatów, zasadniczo chcesz .aggregate() w celu pobrania dokumentów z tym samym RegisterNumber wartość i usuń wszystkie inne dokumenty poza pierwszym dopasowaniem.

MongoDB 3.0.x brakuje niektórych nowoczesnych pomocników, ale podstaw, które .aggregate() zwraca kursor dla dużych zestawów wyników procesu i obecności "operacji zbiorczych" dla wydajności zapisu nadal istnieje:

var bulk = db.collection.initializeOrderedBulkOp();
var count = 0;

db.collection.aggregate([
  // Group on unique value storing _id values to array and count 
  { "$group": {
    "_id": "$RegisterNumber",
    "ids": { "$push": "$_id" },
    "count": { "$sum": 1 }      
  }},
  // Only return things that matched more than once. i.e a duplicate
  { "$match": { "count": { "$gt": 1 } } }
]).forEach(function(doc) {
  var keep = doc.ids.shift();     // takes the first _id from the array

  bulk.find({ "_id": { "$in": doc.ids }}).remove(); // remove all remaining _id matches
  count++;

  if ( count % 500 == 0 ) {  // only actually write per 500 operations
      bulk.execute();
      bulk = db.collection.initializeOrderedBulkOp();  // re-init after execute
  }
});

// Clear any queued operations
if ( count % 500 != 0 )
    bulk.execute();

W bardziej nowoczesnych wydaniach ( 3.2 i nowsze ) preferowane jest użycie bulkWrite() zamiast. Zauważ, że jest to „biblioteka klienta”, ponieważ te same metody „zbiorcze” pokazane powyżej są w rzeczywistości nazywane „pod maską”:

var ops = [];

db.collection.aggregate([
  { "$group": {
    "_id": "$RegisterNumber",
    "ids": { "$push": "$id" },
    "count": { "$sum": 1 }      
  }},
  { "$match": { "count": { "$gt": 1 } } }
]).forEach( doc => {

  var keep = doc.ids.shift();

  ops = [
    ...ops,
    {
      "deleteMany": { "filter": { "_id": { "$in": doc.ids } } }
    }
  ];

  if (ops.length >= 500) {
    db.collection.bulkWrite(ops);
    ops = [];
  }
});

if (ops.length > 0)
  db.collection.bulkWrite(ops);

Więc $group ściąga wszystko razem za pomocą $RegisterNumber wartość i zbiera pasujący dokument _id wartości do tablicy. Liczysz, ile razy to się dzieje, używając $sum .

Następnie odfiltruj wszystkie dokumenty, które miały tylko 1 ponieważ to wyraźnie nie są duplikaty.

Przechodząc do pętli usuwasz pierwsze wystąpienie _id na zebranej liście dla klucza z .shift() , pozostawiając tylko inne "duplikaty" w tablicy.

Są one przekazywane do operacji „remove” za pomocą $in jako „lista” dokumentów do dopasowania i usunięcia.

Proces jest generalnie taki sam, jeśli potrzebujesz czegoś bardziej złożonego, takiego jak scalanie szczegółów z innych duplikatów dokumentów, po prostu możesz potrzebować większej ostrożności, jeśli robisz coś takiego jak konwersja przypadku „unikalnego klucza”, a zatem faktycznie najpierw usuwasz duplikaty przed zapisaniem zmian w dokumencie, który ma zostać zmodyfikowany.

W każdym razie agregacja wyróżni dokumenty, które faktycznie są „duplikatami”. Pozostała logika przetwarzania opiera się na tym, co faktycznie chcesz zrobić z tymi informacjami po ich zidentyfikowaniu.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. sortuj według długości łańcucha w Mongodb/pymongo

  2. Jak przetestować aktualizacje aplikacji MongoDB?

  3. podłączenie mongodb stworzonego w mongolabie przez aplikację java

  4. Jak ustawić mongo db dbpath w systemie Windows 7?

  5. Błąd podczas instalacji sterownika mongo dla PHP na amazon linux