Удаление элемента _id из результатов Pymongo

Я пытаюсь создать веб-сервис, используя MongoDB и Flask (используя драйвер pymongo). Конечно, запрос к базе данных возвращает документы с включенным полем "_id". Я не хочу отправлять это клиенту, поэтому как его удалить?

Здесь маршрут фляжки:

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

Это возвращает:

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

    ...
    }
]}

Я думал, что это словарь, и я мог просто удалить элемент перед его возвратом:

del objects['_id']

Но это возвращает TypeError:

TypeError: 'Cursor' object does not support item deletion

Таким образом, это не словарь, но что-то, что я должен перебирать с каждым результатом в качестве словаря. Поэтому я пытаюсь сделать это с помощью этого кода:

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

Каждый словарь объектов выглядит так, как мне хотелось бы, но курсор объектов пуст. Поэтому я пытаюсь создать новый словарь и после удаления _id от каждого добавьте новый словарь, возвращаемый Flask:

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

Это просто возвращает словарь с ключами первого уровня и ничего больше.

Итак, это своего рода стандартная проблема с вложенными словарями, но я также шокирован тем, что у MongoDB нет способа легко справиться с этим.

документация MongoDB объясняет, что вы можете исключить _id с помощью

{ _id : 0 }

Но это ничего не делает с пимонго. документация Pymongo объясняет, что вы можете перечислить поля, которые хотите вернуть, но" ( "_id" всегда будет включен) ". Шутки в сторону? Разве это не так? Есть что-то простое и глупое, что я здесь не замечаю?

Ответы

Ответ 1

Чтобы исключить поле _id в запросе поиска в pymongo, вы можете использовать:

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

Документация несколько пропущена на этом, так как он говорит, что поле _id всегда включено. Но вы можете исключить его, как показано выше.

Ответ 2

Вы вызываете

del objects['_id']

на объекте курсора!

Объект курсора, очевидно, является итерируемым по набору результатов, а не одиночным который вы можете манипулировать.

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

скорее всего вы хотите.

Итак, ваше утверждение совершенно неверно, как показано в следующем коде:

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}