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

Bulk update in Pymongo using multiple ObjectId

我想更新 mongo collection 中的数千个文档。我想使用 ObjectId 找到它们,然后应更新匹配的文档。我的更新对所有文件都是一样的。我有 ObjectId 列表。对于列表中的每个 ObjectId,mongo 应该找到匹配的文档并将该文档的 "isBad" 键更新为 "N"

ids = [ObjectId('56ac9d3fa722f1029b75b128'), ObjectId('56ac8961a722f10249ad0ad1')]
bulk = db.testdata.initialize_unordered_bulk_op()
bulk.find( { '_id': ids} ).update( { '$set': {  "isBad" : "N" } } )
print bulk.execute()

这给了我结果:

{'nModified': 0, 'nUpserted': 0, 'nMatched': 0, 'writeErrors': [], 'upserted': [], 'writeConcernErrors': [], 'nRemoved': 0, 'nInserted': 0}

这是预期的,因为它正在尝试将“_id”与列表匹配。但我不知道如何进行。

我知道如何单独更新每个文档。我的列表大小约为 25000。我不想单独拨打 25000 个电话。我的文件数量 collection 多得多。我正在使用 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()

因为写入命令最多可以接受 1000 个操作(来自 docs),你必须将批量操作分成多个批次,在这种情况下你可以选择最多 1000 的任意批量大小。

之所以选择500是为了保证Bulk.find() and the update document is less than or equal to the maximum BSON document size even though there is no there is no guarantee using the default 1000 operations requests will fit under the 16MB BSON limit. The Bulk()操作中关联文档的总和mongoshell而驱动程序中的类似方法没有此限制。

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

    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()