Question

I have a find query in a mongodb collection and would like this query to also update a field... something like this...

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

I found the findandmodify method but could not find any example of how to use it...

Thanks in advance for any help!

Was it helpful?

Solution

Note that the methods in this answer have been deprecated. See Sid Holland's answer for more details.


refer the documentation, for example

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

or find_and_modify according to docs says Returns either the object before or after modification based on new parameter. If no objects match the query and upsert is false, returns None. If upserting and new is false, returns {}


for example:

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!'}]

OTHER TIPS

For those that came here after Googling find_and_modify and discovered it is deprecated (in PyMongo version 3.0, I think), the replacement is find_one_and_update.

Let's say you have a collection called counters and want to increment one of the counters:

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

If you want the new document returned, instead of the original pre-updated one, the parameter to pass is new and not, as most documentation states, returnNewDocument:

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

Since find_and_modify is deprecated use find_one_and_update method instead, use return_document parameter of find_one_and_update method to return either updated document or unupdated document.

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

Here, return_document is set as ReturnDocument.AFTER, which will return a document after it's updated. If it's set as BEFORE, it'll return the document before it was updated.

Use update_one to update a single document in a collection and set upsert to True to create a new document if condition doesn't match.

collection.update_one(
    filter = {"field1" : "value1"},
    update = {"$set" : {"field2" : "value2"}},
    upsert = True
)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top