9

我想更新 mongo 集合中的数千个文档。我想使用 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 次电话。我收藏的文件数量要多得多。我正在使用 python2,pymongo = 3.2.1。

4

3 回答 3

18

使用 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()更新文档和更新文档的关联文档的总和小于或等于最大 BSON 文档大小,即使没有使用默认的 1000 操作请求也不能保证适合下16MB BSON 限制。mongo shell 中的Bulk()操作和驱动程序中的类似方法没有此限制。

于 2016-02-18T12:02:05.687 回答
3
bulk = db.testdata.initialize_unordered_bulk_op()

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

bulk.execute()
于 2021-01-16T00:26:19.373 回答
-2

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

    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()
于 2016-02-18T12:06:23.060 回答