Python 在Pymongo中使用多个ObjectId进行批量更新

Python 在Pymongo中使用多个ObjectId进行批量更新,python,mongodb,python-2.7,pymongo,pymongo-3.x,Python,Mongodb,Python 2.7,Pymongo,Pymongo 3.x,我想更新mongo collection中的数千个文档。我希望使用ObjectId找到它们,然后更新与之匹配的文档。我的更新对所有文档都是相同的。我有ObjectId的列表。对于列表中的每个ObjectId,mongo应该找到匹配的文档,并将该文档的“isBad”键更新为“N” 这给了我一个结果: {'nModified': 0, 'nUpserted': 0, 'nMatched': 0, 'writeErrors': [], 'upserted': [], 'writeConcernErro

我想更新mongo collection中的数千个文档。我希望使用ObjectId找到它们,然后更新与之匹配的文档。我的更新对所有文档都是相同的。我有ObjectId的列表。对于列表中的每个ObjectId,mongo应该找到匹配的文档,并将该文档的“isBad”键更新为“N”

这给了我一个结果:

{'nModified': 0, 'nUpserted': 0, 'nMatched': 0, 'writeErrors': [], 'upserted': [], 'writeConcernErrors': [], 'nRemoved': 0, 'nInserted': 0}
这是预期的,因为它正在尝试将“\u id”与列表匹配。但我不知道如何继续


我知道如何单独更新每个文档。我的名单大约有25000份。我不想单独打25000个电话。我收藏的文档数量要多得多。我使用的是python2,pymongo=3.2.1。

使用for循环迭代id列表,并以500个批次发送批量更新:

bulk = db.testdata.initialize_unordered_bulk_op()
counter = 0

for id in ids:
    # process in bulk
    bulk.find({ '_id': id }).update({ '$set': { 'isBad': 'N' } })
    counter += 1

    if (counter % 500 == 0):
        bulk.execute()
        bulk = db.testdata.initialize_ordered_bulk_op()

if (counter % 500 != 0):
    bulk.execute()

由于write命令最多只能接受1000个操作(来自),因此必须将批量操作拆分为多个批,在这种情况下,您可以选择最大为1000的任意批大小


选择500的原因是为了确保来自的关联文档和更新文档的总和小于或等于最大BSON文档大小,即使没有保证使用默认1000操作请求将符合16MB BSON限制。mongo shell中的操作和驱动程序中的类似方法没有此限制。

我得到了答案,可以这样做:

    bulk = db.testdata.initialize_unordered_bulk_op()
    for i in range (0, len(ids)):
        bulk.find( { '_id':  ids[i]}).update({ '$set': {  "isBad" : "N" }})
    print bulk.execute()

为什么限制为500?@chridam我想如果内存超过限制,它会自动分成几个部分。所以我认为,没有必要保留计数器。我说的对吗?不需要拆分批量操作,pymongo会解决这个问题:为什么需要
range
这是低效的。虽然这段代码可以回答这个问题,但提供关于为什么和/或如何回答这个问题的附加上下文可以提高其长期价值。
    bulk = db.testdata.initialize_unordered_bulk_op()
    for i in range (0, len(ids)):
        bulk.find( { '_id':  ids[i]}).update({ '$set': {  "isBad" : "N" }})
    print bulk.execute()
bulk = db.testdata.initialize_unordered_bulk_op()

for id in ids:
   bulk.find( { '_id':  id}).update({ '$set': {  "isBad" : "N" }})

bulk.execute()