35

MongoDBとFlaskを使用して(pymongoドライバーを使用して)Webサービスを作成しようとしています。もちろん、データベースへのクエリは、「_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)

これは、第1レベルのキーだけを含む辞書を返すだけです。

つまり、これは一種の標準的なネストされた辞書の問題ですが、MongoDBにはこれを簡単に処理する方法がないことにもショックを受けています。

MongoDBのドキュメントでは、_idを除外できると説明されています

{ _id : 0 }

しかし、それはpymongoでは何もしません。Pymongoのドキュメントには、返されるフィールドを一覧表示できると説明されていますが、「( "_ id"は常に含まれます)」。真剣に?これを回避する方法はありませんか?私がここで見落としている単純で愚かなものはありますか?

4

3 に答える 3

111

_idpymongo の検索クエリでフィールドを除外するには、次を使用できます。

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

_idドキュメントは、フィールドが常に含まれていると述べているため、これについて誤解を招く可能性があります。ただし、上記のように除外できます。

于 2012-09-10T05:10:04.563 に答える
0

あなたが呼んでいます

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}
于 2012-09-10T04:45:41.690 に答える