Pymongo 查找并修改

18 投票
4 回答
49032 浏览
提问于 2025-04-18 04:46

我在一个mongodb的集合里有一个查找查询,我想让这个查询同时更新一个字段……类似这样……

db = pymongo.MongoClient(DB_HOST)[COLLECTION][Product]
new_posts = db.find({'type':{'$ne':'overview'}, 'indice':0, 'thread_id':{'$nin':front_db_ids}, 'updated':{'$exists':False}},{'_id': 0}) + {{'$set': {'updated':'yes'}}, multi=True

我找到了findandmodify这个方法,但没找到任何使用它的例子……

提前感谢任何帮助!

4 个回答

0

使用 update_one 可以在一个 collection 中更新单个文档。如果条件不匹配,可以把 upsert 设置为 True,这样就会创建一个新的 document

collection.update_one(
    filter = {"field1" : "value1"},
    update = {"$set" : {"field2" : "value2"}},
    upsert = True
)
4

因为 find_and_modify 这个方法已经不再推荐使用,所以要用 find_one_and_update 方法来代替。可以使用 find_one_and_update 方法中的 return_document 参数来决定是返回更新后的文档还是未更新的文档。

update_object = collection_object.find_one_and_update({'_id': ObjectId(pk)}, {'$set': data}, return_document=ReturnDocument.AFTER)

在这里,return_document 被设置为 ReturnDocument.AFTER,这样就会返回更新后的文档。如果设置为 BEFORE,则会返回更新之前的文档。

21

如果你是通过搜索 find_and_modify 来到这里的,可能会发现这个方法已经被弃用了(在 PyMongo 3.0 版本中,我想是这样),现在用的替代方法是 find_one_and_update

假设你有一个叫 counters 的集合,你想要增加其中一个计数器的值:

db.counters.find_one_and_update({"_id": "counter-id"}, {"$inc":{"sequence_value":1}})

如果你想要返回更新后的新文档,而不是更新前的原始文档,你需要传入的参数是 new,而不是大多数文档中提到的 returnNewDocument

db.counters.find_one_and_update({"_id": "counter-id"}, {"$inc":{"sequence_value":1}}, new=True)
26

请注意,这个答案中的方法已经不再推荐使用了。想了解更多信息,可以查看Sid Holland的回答


可以参考文档,比如说:

db.update({"_id": acs_num}, {"$set": mydata}, upsert = True)

或者使用find_and_modify,根据文档的说明,根据new参数的不同,返回修改前或修改后的对象。如果没有对象符合查询条件,并且upsert为假,则返回None。如果进行插入操作且new为假,则返回{}


举个例子:

In [1]: from pymongo import MongoClient

In [2]: client = MongoClient("mongodb://localhost:27017")
   ...: db = client["testdb"]
   ...: mycollection = db["mydb"]
   ...: 

In [3]: import datetime
   ...: post1 = {"author": "Mike", "text": "My first blog post!", "tags": ["mongodb", "python", "pymongo"], "date": datetime.datetime.utcnow()}
   ...: 

In [4]: mycollection.insert(post1)
Out[4]: ObjectId('535fd580c314f91d28c35ee1')

In [5]: [x for x in mycollection.find()]
Out[5]: 
[{u'_id': ObjectId('535fd580c314f91d28c35ee1'),
  u'author': u'Mike',
  u'date': datetime.datetime(2014, 4, 29, 16, 38, 15, 457000),
  u'tags': [u'mongodb', u'python', u'pymongo'],
  u'text': u'My first blog post!'}]

In [6]: mycollection.find_and_modify(query={'author':'Mike'}, update={"$set": {'author': "Mike2"}}, upsert=False, full_response= True)
Out[6]: 
{u'lastErrorObject': {u'n': 1, u'updatedExisting': True},
 u'ok': 1.0,
 u'value': {u'_id': ObjectId('535fd580c314f91d28c35ee1'),
  u'author': u'Mike',
  u'date': datetime.datetime(2014, 4, 29, 16, 38, 15, 457000),
  u'tags': [u'mongodb', u'python', u'pymongo'],
  u'text': u'My first blog post!'}}

In [7]: [ x for x in mycollection.find()]
Out[7]: 
[{u'_id': ObjectId('535fd580c314f91d28c35ee1'),
  u'author': u'Mike2',
  u'date': datetime.datetime(2014, 4, 29, 16, 38, 15, 457000),
  u'tags': [u'mongodb', u'python', u'pymongo'],
  u'text': u'My first blog post!'}]

撰写回答