2016-04-21 40 views
2

如何在迭代期間(使用遊標)刪除文檔?查找期間從集合中刪除文檔

db.users.find().forEach(function(myDoc) { 
    print("user: " + myDoc.name); 
    // now I'm done with it 
    myDoc.remove(); // <-- this doesn't work 
}); 

有沒有辦法做到這一點,而無需做單獨的搜索?

db.users.find().forEach(function(myDoc) { 
    print("user: " + myDoc.name); 
    // now I'm done with it 
    db.users.findOneAndDelete(myDoc); // <-- this does work 
}); 

雖然後面的工作,似乎在已經擁有該文件後進行搜索會顯着減慢進程。 (我錯了嗎?)

+1

這不是一個好主意,因爲您需要爲每個文檔執行'db.collection.deleteOne(myDoc)'。我建議你檢索所有想要刪除的文件的_id,並在完成時使用'db.collection.deleteMany()'。 – styvane

+0

我擔心的是缺乏原子性,我正在建立一個要求,在任何時候機器都會關閉。我擔心的是,在任何時候我在許多文檔上進行處理並且不刪除「直到所有更新完成後,我都會得到很多重複文件。偶爾複製單個文檔在合理範圍內。 – Daniel

回答

3

你可以先搜索對象,並保持_id S IN的數組。然後使用以下代碼刪除所有元素一次。

db.users.deleteMany(
     { "_id": {$in:idArray} }, 
     function(err, results) { 

     } 
    ); 

編輯

我發現了一個大容量的方法來做到這一點。

var bulk = db.users.initializeUnorderedBulkOp(); 
bulk.find({ "_id": {$in:idArray} }).remove(); 
bulk.execute(); 

根據我的experiance,你可以,如果你使用的批量操作,因爲它減少IO操作減少執行時間超過10個時間快。

+0

這是比採取OP更好的方法,但只是爲了糾正您的術語,這是**不是**明確說出的批量操作操作。 '.deleteMany()'只是調用'.remove()'調用區分包含或排除''justOne「'選項,就像'.update()'一樣,可以選擇是否影響「所有」匹配的文件或不是,但它不是「真正」所謂的「批量」操作。從技術上講,「所有」MongoDB寫操作API函數實際上使用下面的Bulk API。即使它們隻影響一個文檔。 –

+0

@NeilLunn,謝謝先生,還有沒有任何Bulk方法從Mongodb中刪除? –

+0

那麼,如果你閱讀[「Bulk」](https://docs.mongodb.org/manual/reference/method/Bulk/)。但是除非通過'$ in'提供列表是不實際的,否則就不需要那麼做了。但是,由於兩者本質上都涉及將大數組(無論是_id值還是操作)發送到服務器,所以這是一個有爭議的問題。 –

2

您可以使用findAndModify。瞭解更多關於它here

db.collection.findAndModify({ 
    query: <document>, 
    remove: <boolean> 
}); 

該函數將返回刪除的文檔,你可以用它來打印。你可以循環它,直到沒有更多的文件。

編輯

你可以採取另一種方法是使用findbulkWrite(deleteMany)。 首先查找並打印所有文檔。然後使用批量寫入操作刪除它們。

db.users.find().forEach(function(myDoc) { 
    print("user: " + myDoc.name); 
}); 

//This is much faster than your current approach of 
//finding and deleting singe documents 

db.users.bulkWrite([ 
    { 
     removeMany: <query> 
    } 
]); 

bulkWrite() - MongoDB

+0

看起來不錯,但不幸的是,一次只能做一個文檔,而不是返回一個遊標。 – Daniel

+0

@Daniel那麼,那有什麼問題呢? – ayushgp

+0

我(可能錯誤地)認爲與批量操作相比,存在性能損失。我沒有意識到'bulkWrite'有能力刪除。我會試一試,看起來很有希望。 – Daniel