2012-09-10 13 views
16

Estoy intentando crear un servicio web usando MongoDB y Flask (usando el controlador pymongo). Una consulta a la base de datos devuelve documentos con el campo "_id" incluido, por supuesto. No quiero enviar esto al cliente, entonces, ¿cómo lo elimino?Eliminando el elemento _id de los resultados de Pymongo

Aquí es una ruta Frasco:

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

Esto devuelve:

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

    ... 
    } 
]} 

me pareció que era un diccionario y tan sólo pudiera eliminar el elemento antes de devolverlo:

del objects['_id'] 

Pero eso devuelve un TypeError:

TypeError: 'Cursor' object does not support item deletion 

Así que no es un diccionario, sino algo que tengo que repetir con cada resultado como un diccionario. Así que trato de hacer eso con este código:

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

Cada diccionario de objetos se ve la forma en que me gustaría que ahora, pero el cursor objetos está vacía. Así que trato de crear un nuevo diccionario y después de eliminar _id de cada uno, añadir a un nuevo diccionario que volverá Frasco:

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

Esto sólo devuelve un diccionario con las teclas de primer nivel y nada más.

Así que este es un tipo de problema de diccionarios anidados estándar, pero también estoy sorprendido de que MongoDB no tenga una forma de lidiar fácilmente con esto.

El MongoDB documentation explica que puede excluir _id con

{ _id : 0 } 

Pero eso no hace nada con pymongo. El Pymongo documentation explica que puede enumerar los campos que desea devolver, pero "(" _id "siempre se incluirá)". ¿Seriamente? ¿Hay forma de evitar esto? ¿Hay algo simple y estúpido que estoy pasando por alto aquí?

+0

¿Cuál es su reclamo real aquí? Tu código para crear un nuevo dict es extraño y no es necesario. ¿Cuál es tu problema real? –

+0

Mi problema era que .find ({}, {'_id': False}) no excluía _id. Sin embargo, era un problema con mi código y ahora está funcionando. Gracias por tu ayuda. – ddw

+0

"pero el cursor de objetos está vacío": eso se debe a que puede iterar solo una vez, por lo que necesitaría iterar, obtener la siguiente dicción, eliminar '_id', poner dict en una lista, y al final devolver esa lista, no objetos. –

Respuesta

53

excluir el sector _id en una consulta hallazgo en pymongo, puede utilizar:

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

La documentación es un tanto No es acertada en esto ya que dice que el campo _id siempre está incluido.Pero puedes excluirlo como se muestra arriba.

+0

Gracias, esto es correcto. Lo intenté antes de publicarlo, pero creo que hubo un problema con la cadena que estaba pasando en el primer parámetro. Lo arreglé y ahora todo está bien. – ddw

2

Usted está llamando

del objects['_id'] 

en el objeto cursor!

El objeto de cursor es obviamente iterable sobre el conjunto de resultados y no solo el documento que puede manipular.

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

es probable que lo que desea.

Así que su reclamo es totalmente erróneo como en el código siguiente:

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} 
+0

Sí, probé tu código también antes de publicar originalmente. ¿Pero cómo combinaría estos diccionarios anidados en un diccionario que se puede pasar al cliente? Además, me di cuenta de que estaba tratando de delisar un objeto de cursor, por eso dije "Así que no es un diccionario, sino algo sobre lo que tengo que iterar con cada resultado como un diccionario". Tal vez debería haber omitido mi proceso de descubrimiento, pero pensé que cuanta más información, mejor. – ddw

Cuestiones relacionadas