Pymongo find and modify
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!
Answers:
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!'}]
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
)
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!
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!'}]
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
)