使用Pymongo更新MongoDB中的选定字段

问题描述 投票:1回答:1

我希望我的python(scrapy)脚本:

  • 如果url不存在,请在我的数据库中插入文档
  • 如果文档存在则仅更新URL字段,并且不更新其他字段。

我的脚本部分工作,因为如果url不存在(我想要的话)它会插入一个新文档,但如果文档存在(我不想要),它会更新所有其他字段。你能帮我吗 ?

这是一个示例:

def process_item(self, item, spider):

        for data in item:
            if not data:
                raise DropItem("Missing data!")

        self.collection.update({'userurl': item['userurl']}, dict(item), upsert=True)

        return item

谢谢 !

python mongodb scrapy pymongo
1个回答
1
投票

我假设url和userurl是两个不同的字段,否则将无法确定MongoDB是否更改了网址或我们有新记录。

使用upsert=True更新将始终更改提供的所有密钥。对于您的特定情况,您可能无法解决两个查询,因为您希望更新另一组字段而不是插入。

根据更常见的情况,您可以通过先尝试更常见(插入或更新)并在第一个失败时发出另一个来减少实际查询的数量。您可以在集合上创建唯一索引以支持此类结构。

像这样的东西(使用最新的pymongo API):

some_collection.create_index('userurl', unique=True)

try:
    collection.insert_one(dict(item))
except pymongo.errors.DuplicateKeyError:
    res = collection.update_one(
       {'userurl': item['userurl'}, {'$set': {'url': item['url'}})

两件事情。

您应该将索引创建放在仅发生一次的位置。您不想一遍又一遍地重新创建索引。

您应该首先尝试更常见的操作。但是,update_one不会在返回零记录的过滤器上失败。检查res.modified_count == 0而不是。

© www.soinside.com 2019 - 2024. All rights reserved.