mongodb - 机器猫 : Exceeded memory limit for $group

标签 mongodb duplicates out-of-memory

我正在使用一个脚本来删除 mongo 上的重复项,它在一个包含 10 个项目的集合中工作,我将其用作测试,但是当我用于包含 600 万个文档的真实集合时,我得到了一个错误。

这是我在 Robomongo 中运行的脚本(现在称为 Robo 3T):

var bulk = db.getCollection('RAW_COLLECTION').initializeOrderedBulkOp();
var count = 0;

db.getCollection('RAW_COLLECTION').aggregate([
  // Group on unique value storing _id values to array and count 
  { "$group": {
    "_id": { RegisterNumber: "$RegisterNumber", Region: "$Region" },
    "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.getCollection('RAW_COLLECTION').initializeOrderedBulkOp();  // re-init after execute
  }
});

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

这是错误信息:

Error: command failed: {
    "errmsg" : "exception: Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in.",
    "code" : 16945,
    "ok" : 0
} : aggregate failed :
_getErrorWithCode@src/mongo/shell/utils.js:23:13
doassert@src/mongo/shell/assert.js:13:14
assert.commandWorked@src/mongo/shell/assert.js:266:5
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1215:5
@(shell):1:1

所以我需要设置 allowDiskUse:true 才能工作?我在脚本中的哪个位置执行此操作,这样做有什么问题吗?

最佳答案

{ allowDiskUse: true } 

应该放在聚合管道之后。

在你的代码中应该是这样的:

db.getCollection('RAW_COLLECTION').aggregate([
  // Group on unique value storing _id values to array and count 
  { "$group": {
    "_id": { RegisterNumber: "$RegisterNumber", Region: "$Region" },
    "ids": { "$push": "$_id" },
    "count": { "$sum": 1 }      
  }},
  // Only return things that matched more than once. i.e a duplicate
  { "$match": { "count": { "$gt": 1 } } }
], { allowDiskUse: true } )

注意:使用 { allowDiskUse: true } 可能会引入与性能相关的问题,因为聚合管道将从磁盘上的临时文件中访问数据。还取决于磁盘性能和工作集的大小。测试用例的性能

关于mongodb - 机器猫 : Exceeded memory limit for $group,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44161288/

相关文章:

c# - 使用 AND 和 OR

regex - 如何从大量 URL 列表中删除重复域?正则表达式或其他

mysql - 根据多列获取mysql中的重复记录

C# 如何消除comboBox 中的重复值?

Java新线程需要内存

通过套接字发送图像时的Java OutOfMemory

c# - 尽管没有进行算术运算,但 IMongoCollection<T>.UpdateOneAsync 中出现 OverflowException

java - 字段 Spring Mongo Data 1.8.2 的发现周期

node.js - find(...).populate 不是 mongoose 中的函数

mysql - 在非常大的表上使用 Count 进行分组