繁体   English   中英

如何使用PyMongo迭代和更新文档?

[英]How to iterate and update documents with PyMongo?

我有一个简单的单客户端设置MongoDB和PyMongo 2.6.3。 目标是迭代集合collection中的每个文档,并更新( save )流程中的每个文档。 我正在使用的方法大致如下:

cursor = collection.find({})
index = 0
count = cursor.count()
while index != count:
    doc = cursor[index]
    print 'updating doc ' + doc['name']
    # modify doc ..
    collection.save(doc)
    index += 1
cursor.close()

问题是save显然正在修改游标中文档的顺序。 例如,如果我的集合由3个文档组成(为清楚起见,省略了id ):

{
    "name": "one"
}
{
    "name": "two"
}
{
    "name": "three"
}

上述计划产出:

> updating doc one
> updating doc two
> updating doc two

但是,如果删除了行collection.save(doc) ,则输出变为:

> updating doc one
> updating doc two
> updating doc three

为什么会这样? 安全地迭代更新集合中的文档的正确方法是什么?

在MongoDB 文档中找到答案:

由于游标在其生命周期内未被隔离,因此对文档进行干预写入操作可能会导致光标在文档发生更改时多次返回文档。 要处理此情况,请参阅有关快照模式的信息。

光标上启用了快照模式,这是一个很好的保证:

snapshot()遍历_id字段上的索引,并保证查询将返回每个文档(相对于_id字段的值)不超过一次。

要使用PyMongo启用快照模式:

cursor = collection.find(spec={},snapshot=True)

根据PyMongo find() 文档 确认这解决了我的问题。

快照完成工作。

但是在pymongo 2.9和之后,语法略有不同。

cursor = collection.find(modifiers={"$snapshot": True})

或任何版本,

cursor = collection.find({"$snapshot": True})

根据PyMongo文档

我无法重新创建你的情况,但也许,在我的头脑中,因为获取结果就像你正在做的那样从db中逐一获取它们,你实际上是在创建更多的东西(保存然后获取)下一个)。

您可以尝试将结果保存在列表中(这样,您一次获取所有结果 - 可能很重 ,具体取决于您的查询):

cursor = collection.find({})
# index = 0
results = [res for res in cursor] #count = cursor.count()
cursor.close()
for res in results: # while index != count //This will iterate the list without you needed to keep a counter:
    # doc = cursor[index] // No need for this since 'res' holds the current record in the loop cycle
    print 'updating doc ' + res['name'] # print 'updating doc ' + doc['name']
    # modify doc ..
    collection.save(res)
    # index += 1 // Again, no need for counter

希望能帮助到你

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM