我的重复删除代码(在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
}
此错误的原因是什么?我怎么能解决这个问题?
更新
在forEach
之前,结果为:
{ "_id" : { <duplicated_keys>: <dupkey_values> }, "dups" : [ ObjectId("56f8e4d37a88ea2aa938414d"), ObjectId("56f63ab87a88ea141ca33856") ], "count" : 2 }
如果我找到ObjectId("56f63ab87a88ea141ca33856")
,那就是重复的文件。
答案 0 :(得分:5)
最后想出了解决方案。 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(...);
答案 1 :(得分:1)
请参阅此问题https://jira.mongodb.org/browse/SERVER-13358,由于游标在聚合中失败而导致此错误Error: getMore command failed:
。请参阅同一问题https://jira.mongodb.org/browse/SERVER-6036,计划修复但未安排
答案 2 :(得分:0)
非常感谢您分享您的发现。我得到了同样的错误,添加noCursorTimeout()帮助处理我的数据。