2

Flask アプリ (mongoengine) で mongoDB (mongoHQ) を使用しています。私はDocument次のようなものを持っています:

{items: [{id: 1}, {id: 2}, {id: 3}]}

たとえば、単一のクエリdictで withに到達する方法はありますか?id: 1

現在、ステートメントを使用してitemsリストをループしていますが、より賢明な解決策を望んでいました。next()ありがとう

4

2 に答える 2

7

私は MongoEngine に詳しくありませんが、$ 射影演算子は配列をフィルター処理して、一致した要素のみを表示することができます。Mongo シェルの場合:

> db.foo.insert({"items": [{"id": 1}, {"id": 2}, {"id": 3}]})
> db.foo.find({'items.id': 1}, {'items.$': true})
{ "_id" : ObjectId("51ce29b68b178484ff2a01ed"), "items" : [  {  "id" : 1 } ] }

詳細: http://docs.mongodb.org/manual/reference/projection/positional/

それはMongoEngineであなたがしているようです:

Foo.objects(__raw__={'items.id': 1}).only('items.$')

詳細: http://mongoengine-odm.readthedocs.org/en/latest/guide/querying.html#raw-queries

于 2013-06-29T00:27:57.977 に答える
0

DB クエリまたは python ステートメントで?

パイソンの使用:

In [21]: d = {"items": [{"id": 1}, {"id": 2}, {"id": 3}]}

In [22]: [i for i in d["items"] if i["id"] == 1]
Out[22]: [{'id': 1}]

[0](リストcompの最後に追加して、辞書を取得するだけです)

ジェネレーターを使用することもできます:

In [23]: (i for i in d["items"] if i["id"] == 1)
Out[23]: <generator object <genexpr> at 0x052A1D50>

In [24]: _.next()
Out[24]: {'id': 1}

DBから返されたレコードに取り組んでいるので、私は個人的に上記の方法でそれを行います。

フィールドを直接抽出する場合 (最初に返されたドキュメントのみが必要であると仮定{"id":1}します):

In [35]: class Doc(Document):
    ...:     items = ListField(DictField())
    ...:     

In [36]: newdoc = Doc(items=[{"id":1},{"id":2},{"id":3}])

In [37]: newdoc.save()
Out[37]: <Doc: Doc object>

In [38]: for document in [d for d in Doc.objects(items__id=1).first().items if d["id"]==1]:
    ...:     print document
    ...:     
{u'id': 1}

フィールド実際には辞書のリストであるため、一致する辞書だけを抽出するのは困難です。一致するフィールドの一部のみを返すようにクエリを変更しても、速度を節約することはできません。代わりに、完全なフィールドを返し、Python から必要なビットを取得するだけです。同じ速度で、維持が容易です。

于 2013-06-28T09:16:41.750 に答える