MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Премахване на дубликати на mongodb

ако сте готови просто да изхвърлите всички други дубликати, тогава всъщност искате да .aggregate() за да съберете документите със същия RegisterNumber стойност и премахнете всички други документи, различни от първото съвпадение.

На MongoDB 3.0.x липсват някои от съвременните помощници, но основите, които .aggregate() връща курсор за големи набори от резултати на процеса и наличието на "групови операции" за производителност при запис все още съществува:

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();

В по-модерни версии (3.2 и по-нови) се предпочита да се използва bulkWrite() вместо. Имайте предвид, че това е нещо от „клиентска библиотека“, тъй като същите „групови“ методи, показани по-горе, всъщност се наричат ​​„под капака“:

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);

Така че $group събира всичко заедно чрез $RegisterNumber стойност и събира съответстващия документ _id стойности към масив. Вие поддържате броя на това колко пъти се случва това, като използвате $sum .

След това филтрирайте всички документи, които имат само брой 1 тъй като очевидно не са дубликати.

Преминавайки към цикъла, премахвате първото срещане на _id в събрания списък за ключа с .shift() , оставяйки само други „дубликати“ в масива.

Те се предават на операцията „премахване“ с $in като „списък“ с документи за съпоставяне и премахване.

Процесът като цяло е същият, ако имате нужда от нещо по-сложно, като например обединяване на детайли от други дублиращи се документи, просто може да се нуждаете от повече внимание, ако правите нещо като преобразуване на регистъра на „уникалния ключ“ и следователно действително първо премахване на дубликатите преди да напишете промени в документа, който ще бъде модифициран.

Във всеки случай агрегирането ще подчертае документите, които всъщност са „дубликати“. Останалата логика на обработка се основава на това, което всъщност искате да направите с тази информация, след като ги идентифицирате.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как да конвертирам от тип данни низ към дата?

  2. най-добра практика за синхронизиране на данни в nodejs

  3. Как да превърна MongoDB заявка в JSON?

  4. Как да извлека създадената дата от Mongo ObjectID

  5. как да актуализирате числово поле, като използвате друго числово поле в MongoDB