删除重复项时出现MongoDB错误

删除重复项时出现MongoDB错误,mongodb,Mongodb,我的重复删除代码(在MongoDB shell中)如下所示: db.<collection_name>.aggregate([ { $group: { _id: { <duplicated_keys>: "$<duplicated_keys>" }, dups: { $addToSet: "$_id" }, count: { $sum: 1 } }

我的重复删除代码(在MongoDB shell中)如下所示:

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
}
这个错误的原因是什么?我怎样才能解决这个问题呢

更新

  • MongoDB版本是3.2
  • 在forEach之前,结果是:

    { "_id" : { <duplicated_keys>: <dupkey_values> }, "dups" : [ ObjectId("56f8e4d37a88ea2aa938414d"), ObjectId("56f63ab87a88ea141ca33856") ], "count" : 2 }
    
    {u id:{:},“DUP”:[ObjectId(“56f8e4d37a88ea2aa938414d”),ObjectId(“56f63ab87a88ea141ca33856”),“count”:2}
    
    如果我用
    ObjectId(“56f63ab87a88ea141ca33856”)
    找到,它就是重复的文档

  • 数据量相对较大(30+GB),这可能是问题所在吗
  • 运行查询时,同一集合中存在插入

请参阅此问题,此错误
错误:getMore命令失败:
由聚合中的游标失败引起。针对同一问题,计划修复但未计划

最终找到了解决方案。MongoDB中的光标有一个生存时间,默认为10分钟。一旦超过此时间,shell将无法再找到下一个光标

要避免这种情况,请使用
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(...);
db..aggregate([
{
$group:{
_id:{:“$”},
DUP:{$addToSet:“$\u id”},
计数:{$sum:1}
}
},
{
$match:{
计数:{$gt:1}
}
},
{
$out:“临时集合”
}
],{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 });

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(...);
db..aggregate([
{
$group:{
_id:{:“$”},
DUP:{$addToSet:“$\u id”},
计数:{$sum:1}
}
},
{
$match:{
计数:{$gt:1}
}
},
{
$out:“临时集合”
}
],
{
allowDiskUse:是的,
游标:{batchSize:0}
});
db.tempCollection.find().forEach(…);

非常感谢分享您的发现。我遇到了同样的错误,添加noCursorTimeout()有助于处理我的数据。

@zangw-Hi,谢谢回复。不,不是
\u id
,它们是一些其他字段,使文档重复。@zangw我已经更新了我的问题。@zangw奇怪。。。这可能是因为数据量大(30+GB)?游标的大小有限制吗?这里也有相同的问题吗?参考我所附的问题,庞大的数据似乎是根本原因……为了让您了解情况,每个答案下都有一个“添加评论”按钮,这样的小评论更好;)@BJ_uuu不要写一个回答来表示感谢。。。也没有说谢谢的评论,只是投票赞成答案