我正在尝试迭代Mongo shell中的游标来更新集合中的所有文档。
我的目标是重命名文档中的某些字段,因此代码看起来像这样:
var cursor = db.collection.find();
while ( cursor.hasNext() )
{
var doc = cursor.next();
printjson(doc);
db.collection.update( { _id : doc._id },
{ $set : { docId : doc.docID,
createdAt : doc.dateAdded,
updatedAt : doc.dateAdded },
$unset : { dateAdded : "",
docID : "" } }
);
}
代码非常简单,所以当我在一些更新的文档中将字段docId
,createdAt
和updatedAt
设置为null
时,我感到非常惊讶,尽管在此之前更新这些字段具有合理的值。
经过一些调试操作并将printjson
添加到代码后,结果发现循环首先迭代了集合中的所有文档,但随后它没有停止迭代并再次循环遍历已更新的文档。顺便说一下,光标中的文档数量不会根据cursor.count()
更改。
我试图找出光标的这种行为是一个错误还是一些奇怪的功能。我使用的是Ubuntu 12.10和Mongo 2.4.6。
提前谢谢。
PS是的,我知道$rename
标签。但是,如果在已更新的文档中不再存在dateAdded,则在尝试设置字段updatedAt时会遇到同样的问题。这并没有拒绝奇怪的游标行为。
答案 0 :(得分:2)
MongoDb的一个功能是光标可以反映之前所做的更改。游标不是孤立的。您需要修改循环以处理此功能。
光标隔离因为光标在其期间未被隔离 生命周期,对文档进行干预写操作可能会导致a 如果该文档具有多次返回文档的游标 改变。要处理此情况,请参阅有关快照模式的信息。