2013-04-26 44 views
2

我有一個包含1億個文檔的集合。我想安全地更新許多文檔(安全地說,我的意思是隻有在文檔尚未更新時才更新文檔)。在Mongo中有沒有一種有效的方法?Mongodb更新數量有限的文檔

我打算使用具有限制子句的$ isolated操作符,但似乎mongo不支持限制更新。

這似乎很簡單,但我卡住了。任何幫助,將不勝感激。

+1

嗯,我再也不能向你提出一個JIRA鏈接了,我很害怕:https://jira.mongodb.org/browse/SERVER-1599 – Sammaye 2013-04-26 13:17:51

+0

謝謝。我註冊的只是爲了這個問題投票:-)現在找到一些令人費解的解決方法,直到功能實施... – jckdnk111 2013-04-26 13:25:48

+0

「安全」 - 我不清楚爲什麼限制與此有關 - 如果您計劃更新所有文檔,並使用「{multi:true}」,那麼每個文檔將只更新一次。你能解釋一下你的確切用例嗎?我懷疑可能會有解決辦法。 – 2013-04-26 15:04:18

回答

1

Per Sammaye,它看起來不像有一個「適當」的方式來做到這一點。 我的解決方法是創建一個sequence as outlined on the mongo site,並簡單地爲我的集合中的每條記錄添加一個「seq」字段。現在我有一個獨特的領域,這是可靠排序更新。

可靠排序在這裏很重要。我打算對自動生成的_id進行排序,但我很快意識到自然順序與ObjectId的升序不同(從this page開始,它看起來像字符串值優先於與我觀察到的行爲相匹配的對象值測試)。另外,將記錄重新定位到磁盤上是完全可能的,這使得排序的自然順序不可靠。

因此,現在我可以查詢具有最小'seq'的記錄,該記錄尚未更新以獲得包含的起點。接下來,我查詢'seq'大於我的起始點並跳過的記錄(跳過這一點非常重要,因爲'seq'可能會稀疏,如果您刪除文檔等...)我想要更新的記錄數。對該查詢設置1的限制,並且您有一個非包含端點。現在我可以使用'updated'= 0,'seq'> =我的出發點和<我的端點進行更新。假設沒有其他線程毆打我的衝擊更新應該給我我想要的。

這裏又是具體步驟:

  1. 使用findAndModify
  2. 創建一個自動遞增序列的字段添加到您的收藏它使用自動遞增序列
  3. 查詢找到一個合適的切入點:db.xx.find({更新:0})。sort({seq:1})。limit(1)
  4. 查詢找到合適的端點:db.xx.find({seq:{$ gt: startSeq}})。sort({seq:1})。skip(updateCount).limit(1)
  5. 使用起點和終點更新集合:db.xx.update({updated:0,seq:{$ gte:startSeq},seq:{$ lt:endSeq},$ isolated:1},{updated:1 },{multi:true})

很痛苦,但它完成了工作。