刪除「重複」是一個過程,並沒有簡單的方法來「識別」重複和「刪除」他們作爲一個單一的陳述。這裏的另一個特殊之處是查詢表單不能「典型地」確定數組的大小,並且當然不能在文檔中不存在的情況下進行排序。
所有病例基本上回落到
標識是「重複」的文件列表,然後最好指法要刪除特定文件,或者更重要的是該文件你「唐't'想從可能的重複項中刪除。
處理該列表以實際執行刪除。
考慮到這一點,你希望擁有的2.6或更高版本的現代化的MongoDB在那裏你可以得到從aggregate方法的光標。你也想在這些版本中最佳速度可用Bulk Operations API:
var bulk = db.collection.initializeOrderedBulkOp();
var counter = 0;
db.collection.aggregate([
{ "$project": {
"id": 1,
"size": { "$size": "$someArray" }
}},
{ "$sort": { "id": 1, "size": -1 } },
{ "$group": {
"_id": "$id",
"docId": { "$first": "$_id" }
}}
]).forEach(function(doc) {
bulk.find({ "id": doc._id, "_id": { "$ne": doc.docId }).remove();
counter++;
// Send to server once every 1000 statements only
if (counter % 1000 == 0) {
bulk.execute();
bulk = db.collection.initializeOrderedBulkOp(); // need to reset
}
});
// Clean up results that did not round to 1000
if (counter % 1000 != 0)
bulk.execute();
你仍然可以做同樣的事情與舊版本的MongoDB,但是從.aggregate()
其結果必然是在16MB這是BSON限制。這仍然應該是很多,但使用舊版本,您也可以使用mapReduce輸出到集合。
但是對於一般聚合響應,您會得到一組結果,並且您也沒有其他便捷方法來查找數組的大小。所以多做點工作:
var result = db.collection.aggregate([
{ "$unwind": "$someArray" },
{ "$group": {
"_id": "$id",
"id": { "$first": "$id" },
"size": { "$sum": 1 }
}},
{ "$sort": { "id": 1, "size": -1 } },
{ "$group": {
"_id": "$id",
"docId": { "$first": "$_id" }
}}
]);
result.result.forEach(function(doc) {
db.collection.remove({ "id": doc._id, "_id": { "$ne": doc.docId } });
});
因此,沒有遊標較大的結果,沒有批量操作使每一個「刪除」需要單獨發送到服務器。
所以在MongoDB中沒有「子查詢」,或者即使有超過「兩個副本」的方式來選出您不希望從其他副本中刪除的文檔。但這是通用的方式。就像一個說明,如果數組的「大小」對於諸如「排序」等目的而言是重要的,那麼最好的方法就是將「大小」作爲文檔的另一個屬性,以便它使得這些操作更容易,無需像這裏所做的那樣「計算」。