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

Премахнете дубликатите от MongoDB

„dropDups“ синтаксисът за създаване на индекс е "оттеглен" от MongoDB 2.6 и премахнат в MongoDB 3.0. В повечето случаи не е много добра идея да използвате това, тъй като "премахването" е произволно и всеки "дубликат" може да бъде премахнат. Което означава, че това, което се „премахва“, може да не е това, което наистина искате да премахнете.

Така или иначе се сблъсквате с грешка "дължина на индекса", тъй като стойността на индексния ключ тук би била по-дълга, отколкото е позволено. Най-общо казано, вие не сте "предназначени" да индексирате 43 полета във всяко нормално приложение.

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

ЗАБЕЛЕЖКА :Трудно ми е да повярвам, че вашите документи всъщност съдържат 43 "уникални" полета. Вероятно е „всичко, от което се нуждаете“ е просто да се идентифициратсамо тези полета, които правят документа "уникален" и след това следвайте процеса, както е описано по-долу:

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

Ако имате версия на MongoDB "по-ниска" от 2.6 и нямате групови операции, тогава можете да опитате със стандартен .remove() и вътре в цикъла. Също така отбелязваме, че .aggregate() няма да върне курсор тук и цикълът трябва да се промени на:

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

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




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Какви знаци НЕ са разрешени в имената на полета в MongoDB?

  2. Създайте индекс за заместващи символи в MongoDB

  3. Проектирайте първия елемент в масива към ново поле (обединяване на MongoDB)

  4. Mongoose с mongodb как да върна току-що запазен обект?

  5. Как да направите пълнотекстово търсене в MongoDB