Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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?

What is your actual claim here? Your code for creating a new dict is weird and not necessary. What is your real problem? – Andreas Jung Sep 10, 2012 at 5:05 My problem was that .find({}, {'_id': False}) wasn't excluding _id. However it was a problem with my code and it's now working. Thanks for your help. – ddw Sep 10, 2012 at 12:15 “but the objects cursor is empty”: that’s because you can iterate only once, so you’d need to iterate, get next dict, remove '_id', put dict into a list, and at the end return that list, not objects. – merwok Jun 27, 2013 at 20:47

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.

Thanks, this is correct. I had tried this before posting but I guess there was a problem with the string I was passing in the first parameter. I fixed that and now all is good. – ddw Sep 10, 2012 at 12:20

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})
                The '_id': False should be in the second set of curly brackets, not the first (like Thomas' answer).
– wordsforthewise
                Aug 5, 2019 at 23:50

on the cursor object!

The cursor object is obviously an iterable over the result set and not single document that you can manipulate.

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

is likely what you want.

So your claim is completely wrong as the following code shows:

import pymongo
c = pymongo.Connection()
db = c['mydb']
db.foo.remove({})
db.foo.save({'foo' : 42})
for row in db.foo.find():
    del row['_id']
    print row
$ bin/python foo.py 
> {u'foo': 42}
                Yep, I tried your code too before originally posting.  But how would I then combine these nested dictionaries into one dictionary that can be passed to the client?    Also, I realized that I was trying to del on a cursor object, that's why I said "So it isn't a dictionary, but something I have to iterate over with each result as a dictionary."  Maybe I should have left out my discovery process but I thought the more info the better.
– ddw
                Sep 10, 2012 at 12:16
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.