2016-03-28 10 views
3

Моих дубликатов удаления кода (в MongoDB оболочке), как это:MongoDB Ошибки при удалении Дубликатов

db.<collection_name>.aggregate([ 
    { 
     $group: { 
      _id: { <duplicated_keys>: "$<duplicated_keys>" }, 
      dups: { $addToSet: "$_id" }, 
      count: { $sum: 1 } 
     } 
    }, 
    { 
     $match: { 
      count: { $gt: 1 } 
     } 
    } 
], { allowDiskUse: true }) 
.forEach(function(doc) { 
    doc.dups.shift(); 
    db.<collection_name>.remove({ _id: { $in: doc.dups } }); 
}); 

И я получил сообщение об ошибке, как это:

[thread1] Error: getMore command failed: { 
     "ok" : 0, 
     "errmsg" : "Cursor not found, cursor id: 144931661890", 
     "code" : 43 
} 

Что является причиной эта ошибка? И как я могу это решить?

UPDATE

  • MongoDB версия 3.2
  • Перед forEach, результат:

    { "_id" : { <duplicated_keys>: <dupkey_values> }, "dups" : [ ObjectId("56f8e4d37a88ea2aa938414d"), ObjectId("56f63ab87a88ea141ca33856") ], "count" : 2 } 
    

    И если я нахожу с ObjectId("56f63ab87a88ea141ca33856"), это дублирует документ.

  • Объем данных относительно большой (30+ ГБ), может возникнуть проблема?
  • При запуске запроса есть вставки в одну и ту же коллекцию.
+0

@zangw Привет, thx для ответа. Нет, не '_id', это некоторые другие поля, делающие дубликаты документов. – xiGUAwanOU

+0

@zangw Я обновил свой вопрос. – xiGUAwanOU

+0

@zangw Strange ... Может ли это из-за большого объема данных (30 + ГБ)? Есть ли ограничение по размеру курсоров? – xiGUAwanOU

ответ

5

Наконец-то выяснилось решение. Курсор в MongoDB имеет время жизни, по умолчанию это 10 минут. По истечении этого времени оболочка не сможет найти следующий курсор.

Чтобы избежать этого, установите время жизни курсора noCursorTimeout(). Например:

db.<collection_name>.aggregate([ 
    { 
     $group: { 
      _id: { <duplicated_keys>: "$<duplicated_keys>" }, 
      dups: { $addToSet: "$_id" }, 
      count: { $sum: 1 } 
     } 
    }, 
    { 
     $match: { 
      count: { $gt: 1 } 
     } 
    }, 
    { 
     $out: "tempCollection" 
    } 
], { allowDiskUse: true }); 

db.tempCollection.find().noCursorTimeout().forEach(...); 

Или использовать меньше размер партии. Например:

db.<collection_name>.aggregate([ 
    { 
     $group: { 
      _id: { <duplicated_keys>: "$<duplicated_keys>" }, 
      dups: { $addToSet: "$_id" }, 
      count: { $sum: 1 } 
     } 
    }, 
    { 
     $match: { 
      count: { $gt: 1 } 
     } 
    }, 
    { 
     $out: "tempCollection" 
    } 
], 
{ 
    allowDiskUse: true, 
    cursor: { batchSize: 0 } 
}); 

db.tempCollection.find().forEach(...); 
0

Большое спасибо за обмен мнениями. Я получал ту же ошибку, и добавление noCursorTimeout() помогло обработать мои данные.

+1

Просто, чтобы дать вам головы, есть кнопка «добавить комментарий» под каждым ответом, который лучше подходит для небольших комментариев, подобных этому;) – JoeRocc

+0

@BJ_ не пишите ответ, чтобы сказать спасибо ... и не комментарий спасибо, просто проголосуйте за ответ – Roberto

Смежные вопросы