如何在插入Mongo文档后更新它?

95

假设我插入了该文档。

post = { some dictionary }
mongo_id = mycollection.insert(post)

现在假设我想要添加一个字段并更新它。我该怎么做?这似乎行不通.....

post = mycollection.find_one({"_id":mongo_id}) 
post['newfield'] = "abc"
mycollection.save(post)
5个回答

127

在pymongo中,您可以使用以下方式进行更新:

mycollection.update({'_id':mongo_id}, {"$set": post}, upsert=False)

如果在数据库中找不到该帖子,upsert参数将插入新的数据而不是更新。


有关详细信息,请访问mongodb网站上的文档。

更新对于版本大于3,请使用update_one代替update

mycollection.update_one({'_id':mongo_id}, {"$set": post}, upsert=False)

1
@Elliott - 还有其他的选择吗? - ajayramesh

37
mycollection.find_one_and_update({"_id": mongo_id}, 
                                 {"$set": {"newfield": "abc"}})

如果没有id为mongo_id的文档,它将会失败,除非您还使用了upsert=True。否则,这将为您出色地工作。默认情况下,它返回旧的文档。要获取新文档,请传递return_document=ReturnDocument.AFTER。有关所有参数的说明,请参见API

该方法是针对MongoDB 3.0引入的。它已扩展到3.2、3.4和3.6版本。


2
如果你将“_id”替换成另一个字段,如“username”,也是有效的。 - Chris
1
@Chris 当你说“当前的pymongo”时,我们来自未来的人可能没有相同的版本。具体说明是很好的习惯。 - Mnebuerquo
@Mnebuerquo 这是一个非常好的观点,我原来没有注意到。以后的帖子中会注意到的,谢谢。 - Chris
@Chris 编辑帮了很大的忙。谢谢!也感谢未来的我,当我再次需要查找时。 - Mnebuerquo

22
我会这样使用 collection.save(the_changed_dict)。 我刚刚测试过,对我来说仍然有效。以下内容直接引用自pymongo文档save(to_save[, manipulate=True[, safe=False[, **kwargs]]]) 保存此集合中的文档。
如果 to_save 已经有 "_id",则执行 update()(upsert)操作,并覆盖具有该 "_id" 的任何现有文档。否则执行 insert() 操作。在这种情况下,如果 manipulate 为 True,则将 "_id" 添加到 to_save,并且此方法返回已保存文档的 "_id"。如果 manipulate 为 False,则服务器将添加 "_id",但此方法将返回 None。

13

根据最新的PyMongo文档,标题为插入一个文档(插入已被弃用),并遵循防御性编程的方法,您应该按以下方式插入和更新:

result = mycollection.insert_one(post)
post = mycollection.find_one({'_id': result.inserted_id})

if post is not None:
    post['newfield'] = "abc"
    mycollection.save(post)

11

这是一个老问题,但我在寻找答案时偶然发现了它,所以我想提供更新的答案供参考。

saveupdate方法已经被弃用。

save(to_save, manipulate=True, check_keys=True, **kwargs)¶ 在此集合中保存文档。

已弃用 - 改用insert_one()或replace_one()。

版本3.0中已更改:删除safe参数。对于未经确认的写操作,请传递w = 0。

update(spec, document, upsert=False, manipulate=False, multi=False, check_keys=True, **kwargs) 更新此集合中的一个或多个文档。

已弃用 - 改用replace_one(),update_one()或update_many()。

版本3.0中已更改:删除safe参数。对于未经确认的写操作,请传递w = 0。

在OP特定的情况下,最好使用replace_one方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接