我希望我的python(scrapy)脚本:
我的脚本部分工作,因为如果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
谢谢 !
我假设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
而不是。