不斷變化的MONGODB結果集

 

不斷變化的MONGODB結果集

在前幾天的一次php+mongoDB數據庫實做中,遇到了一個很奇怪的問題:

有N張collection,每個collection中有Mn條記錄,我先循環N,去每張collection中find()到所有記錄,然後在針對每條記錄做update()操作,

$mo = new Mongo();

$db =  $mo->dbname;

for($i=0;$i<100;$i++){

$coll = $db->selectCollection(’col’.$i){

$cursor = $coll->find();

while($cursor as $k=>$v){

$uid = $v['uid'];

$rs = $coll->update(array(’uid’=>$uid),array(要更新的內容));

}

}

}

但是實際上,有些記錄被update的兩次,百思不得其解,update()的$option換了所有方式,都無效。

後來,在Sam的幫助下,詳細查了php手冊的mongoDB一段,最後發現:

http://www.php.net/manual/en/mongocursor.snapshot.php

MongoCursor MongoCursor::snapshot()

Use snapshot mode for the query. Snapshot mode assures no duplicates are returned, or objects missed, which were present at both the start and end of the query’s execution (if an object is new during the query, or deleted during the query, it may or may not be returned, even with snapshot mode).
Note that short query responses (less than 1MB) are always effectively snapshotted.
Currently, snapshot mode may not be used with sorting or explicit hints.

大意是:$cursor->snapshot();之後,再插入或者刪除符合條件的記錄時,獲取的結果集將不再變化。如果是小於1M的結果集會自動被當作snapshot來處理。

結論:

1,如果你想或的固定的結果集,那麼在find()之後要snapshot()一下,保證一致性。

2,不管是否小於1M,這一點在我們開發的時候可能不好評估,所以,只要是要固定結果集的,都snapshot好了。

疑問:

1,懷疑這是bug,因爲在說明中並沒有提到update操作會影響結果集,而只提到了刪除和添加對結果集的影響。因爲我update的時候並沒有增加記錄。

2,爲什麼不是一直影響下去?如果我獲得一個結果集,然後在循環過程中做update,那應該就成了個周而復始的循環纔對。而我測試的結果是,循環的次數並不是記錄數量的兩倍,而是不確定次數的循環。

 

 

這個應該不是bug,《mongodb權威指南》P62頁 “獲取一致結果” 裏有描述。 不一致只在遊標等待結果時集合內容被改變的情況下發生。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章