Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing _id element from Pymongo results

I'm attempting to create a web service using MongoDB and Flask (using the pymongo driver). A query to the database returns documents with the "_id" field included, of course. I don't want to send this to the client, so how do I remove it?

Here's a Flask route:

@app.route('/theobjects') def index():     objects = db.collection.find()     return str(json.dumps({'results': list(objects)},          default = json_util.default,         indent = 4)) 

This returns:

{ "results": [     {         "whatever": {             "field1": "value",              "field2": "value",          },          "whatever2": {             "field3": "value"         },         ...         "_id": {             "$oid": "..."         },       ...     } ]} 

I thought it was a dictionary and I could just delete the element before returning it:

del objects['_id'] 

But that returns a TypeError:

TypeError: 'Cursor' object does not support item deletion 

So it isn't a dictionary, but something I have to iterate over with each result as a dictionary. So I try to do that with this code:

for object in objects:     del object['_id'] 

Each object dictionary looks the way I'd like it to now, but the objects cursor is empty. So I try to create a new dictionary and after deleting _id from each, add to a new dictionary that Flask will return:

new_object = {} for object in objects:     for key, item in objects.items():         if key == '_id':             del object['_id']             new_object.update(object) 

This just returns a dictionary with the first-level keys and nothing else.

So this is sort of a standard nested dictionaries problem, but I'm also shocked that MongoDB doesn't have a way to easily deal with this.

The MongoDB documentation explains that you can exclude _id with

{ _id : 0 } 

But that does nothing with pymongo. The Pymongo documentation explains that you can list the fields you want returned, but "(“_id” will always be included)". Seriously? Is there no way around this? Is there something simple and stupid that I'm overlooking here?

like image 448
ddw Avatar asked Sep 10 '12 04:09

ddw


People also ask

Can we override _ID in MongoDB?

The _id field is immutable—that is, once a document exists in your MongoDB system, it has, by definition, been assigned an _id, and you cannot change or update its primary key. That said, _id can be overridden when you insert new documents, but by default it will be populated with an ObjectID.

How do I delete a record in PyMongo?

To delete one document, we use the delete_one() method. The first parameter of the delete_one() method is a query object defining which document to delete. Note: If the query finds more than one document, only the first occurrence is deleted.

How do I delete a specific field in MongoDB?

The $unset operator deletes a particular field. Consider the following syntax: { $unset: { <field1>: "", ... } } The specified value in the $unset expression (i.e. "" ) does not impact the operation.

What does PyMongo Find_one return?

The most basic type of query that can be performed in MongoDB is find_one() . This method returns a single document matching a query (or None if there are no matches).


2 Answers

To exclude the _id field in a find query in pymongo, you can use:

db.collection.find({}, {'_id': False}) 

The documentation is somewhat missleading on this as it says the _id field is always included. But you can exclude it like shown above.

like image 194
Thomas Avatar answered Sep 20 '22 13:09

Thomas


Above answer fails if we want specific fields and still ignore _id. Use the following in such cases:

db.collection.find({'required_column_A':1,'required_col_B':1, '_id': False}) 
like image 38
srikar saggurthi Avatar answered Sep 20 '22 13:09

srikar saggurthi