【问题标题】:pymongo update same field value on large collectionpymongo 在大型集合上更新相同的字段值
【发布时间】:2020-07-22 22:07:15
【问题描述】:

我的 mongo 集合中有超过 1000 万份文档。并且图像文件扩展名 .jpg 在大约 ~600 万份文档 中缺少表单字段 variants.image_url,我想使用缺少扩展名 .jpg 来更新此字段。

我首先运行find 查询以查找所有这些文档,然后运行update 查询以更新它,但这非常慢。我该如何优化呢?

示例:

{“变体”:[{“image_url”:“http://assets.myassets.com/assets/images/2020/3/5/158642332113146/Arrow-ShirtsFossil-Smart-WatchesLee-Cooper-Formal-ShoesRoadster -牛仔裤" } ] }

将改为.jpg

{“变体”:[{“image_url”:“http://assets.myassets.com/assets/images/2020/3/5/158642332113146/Arrow-ShirtsFossil-Smart-WatchesLee-Cooper-Formal-ShoesRoadster -Jeans.jpg" } ] }

# query through all where verion in not v2 and return only variants.image_url
 cursor = collection.find({"version": {"$ne": "v2"}}, {"variants.image_url": 1, "_id": 0})

 modified_count  = 0
 for record in cursor:
    modified_count = modified_count + update_image_url(record) 
 return modified_count


 def update_image_url(record)
    for key1 in record:
        # list
        for idx, elem in enumerate(record[key1]):
            # dict
            for key2 in elem:
                if str(elem[key2])[-4:] == ".jpg" or str(elem[key2])[-4:] == ".JPG":
                    print(".jpg or .JPG extension present. skipping")
                    return 0
                else:
                    query = {"variants.image_url": {"$eq": elem[key2]}}
                    new_value = {"$set": {"variants." + str(idx) + ".image_url": str(elem[key2]) + ".jpg"}}

                    update_result = collection.update(query, new_value)
                    print(update_result["nModified"], "nModified documents updated.")
                    return update_result["nModified"]

【问题讨论】:

  • 你用的是哪个版本的mongodb?
  • mongodb-macos-x86_64-4.2.0
  • 从 4.2 版开始,您可以使用update with aggregation pipeline,它允许您在参考当前值的同时更新文档,因此您不必单独进行查找和更新操作。
  • @thammada.ts 让我试试这个。谢谢!!!
  • 你必须使用不敏感的正则表达式来查找应该更新的文档

标签: python mongodb pymongo


【解决方案1】:

我通过优化第二部分来解决这个问题,即update 查询到 O(1) 时间。我没有使用variants.image_url 上的查询,而是使用_id,并且由于数据在字段_id 上被索引,这需要O(1) 时间。

# return _id as well 
 cursor = collection.find({"version": {"$ne": "v2"}}, {"variants.image_url": 1})

 modified_count  = 0
 for record in cursor:
    modified_count = modified_count + update_image_url(record) 
 return modified_count


 def update_image_url(record)
    for key1 in record:
        # list
        for idx, elem in enumerate(record[key1]):
            # dict
            for key2 in elem:
                if str(elem[key2])[-4:] == ".jpg" or str(elem[key2])[-4:] == ".JPG":
                    print(".jpg or .JPG extension present. skipping")
                    return 0
                else:
                    # query on _id field O(1) time 
                    query = {"_id": {"$eq": record["_id"]}}
                    new_value = {"$set": {"variants." + str(idx) + ".image_url": str(elem[key2]) + ".jpg"}}

                    update_result = collection.update(query, new_value)
                    print(update_result["nModified"], "nModified documents updated.")
                    return update_result["nModified"]

【讨论】:

    猜你喜欢
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 2021-12-05
    • 2019-02-16
    • 1970-01-01
    相关资源
    最近更新 更多