Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Append item to MongoDB document array in PyMongo without re-insertion

I am using MongoDB as the back-end database for Python web application (PyMongo + Bottle). Users can upload files and optionally 'tag' these files during upload. The tags are stored as a list within the document, per below:

{     "_id" : ObjectId("561c199e038e42b10956e3fc"),     "tags" : [ "tag1", "tag2", "tag3" ],     "ref" : "4780" } 

I am trying to allow users to append new tags to any document. I came up with something like this:

def update_tags(ref, new_tag)     # fetch desired document by ref key as dict     document = dict(coll.find_one({'ref': ref}))     # append new tag     document['tags'].append(new_tag)     # re-insert the document back into mongo     coll.update(document) 

(fyi; ref key is always unique. this could easily be _id as well.) It seems like there should be a way to just update the 'tags' value directly without pulling back the entire document and re-inserting. Am I missing something here?

Any thoughts are greatly appreciated :)

like image 638
deadbits Avatar asked Oct 17 '15 17:10

deadbits


People also ask

How do I append to an array in MongoDB?

In MongoDB, the $push operator is used to appends a specified value to an array. If the mentioned field is absent in the document to update, the $push operator add it as a new field and includes mentioned value as its element. If the updating field is not an array type field the operation failed.

How do you update an array element in MongoDB?

You can use the updateOne() or updateMany() methods to add, update, or remove array elements based on the specified criteria. It is recommended to use the updateMany() method to update multiple arrays in a collection.

How do I add an array of strings in MongoDB?

ArrayList<String> stringArray = new ArrayList<String>(); BasicDBObject document = new BasicDBObject(); document. put("master", stringArray); db. getCollection("master"). insert(document);

How do I update all documents in PyMongo?

Updating all Documents in a Collection. PyMongo includes an update_many() function which updates all the documents which satisfy the given query. filter – It is the first parameter which is a criteria according to which the documents that satisfy the query are updated.


2 Answers

You don't need to use to retrieve the document first just use the .update method with the $push operator.

def update_tags(ref, new_tag):     coll.update({'ref': ref}, {'$push': {'tags': new_tag}}) 

Since update is deprecated you should use the find_one_and_update or the update_one method if you are using pymongo 2.9 or newer

like image 108
styvane Avatar answered Sep 28 '22 05:09

styvane


Just to add to @ssytvane answer,and to answer @Guarav: you can add "upsert = True" if it does not exist:

def update_tags(ref, new_tag):     coll.update({'ref': ref}, {'$push': {'tags': new_tag}}, upsert = True) 

or

def update_tags(ref, new_tag):     coll.update_one({'ref': ref}, {'$push': {'tags': new_tag}}, upsert = True) 
like image 43
Kiluvya.A Avatar answered Sep 28 '22 05:09

Kiluvya.A