1

みなさん、良い一日を。次のようなコレクションとドキュメントがあるとします。

    test_doc = {
    "ID" : "123",
    "a" : [
                    {
                        'x' : "/",
                        'y' : "2000",
                        'z' : "1000"
                    },
                    {
                        'x' : "/var",
                        'y' : "3500",
                        'z' : "3000"
                    }
           ]

      }

必要なのは、単一のプロパティ az を取得することです。MongoDB では、次のクエリを使用しています。

db.testcol.find({"ID":"123","a.x":"/"},{'a.z':1})

これはこれを返します:

{ "_id" : ObjectId("skipped"), "a" : [ { "z" : "1000" }, { "z" : "3000" } ] }

ご覧のとおり、すべての z プロパティが返されますが、条件が の場合は最初または 2 番目のプロパティのみが必要です{"ID":"123","a.x":"/var"} 。問題は、この状況で単一のプロパティを取得するにはどうすればよいですか? それは単なる設計の問題ですか、それとも返されたドキュメントをコード (python) で処理する必要がありますか? どんな提案でも大歓迎です。

4

1 に答える 1

1

MongoDB 2.0 以前では、これは不可能です。あなたがしたいのは、配列の特定の要素を返すことですが、それはあなたの射影が実際に行っていることではなく、配列全体とそれぞれの z 要素を返すだけです。

ただし、2.2(この回答を書いている時点でrc2)では、状況は少し良くなりました。プロジェクションの一部として$elemMatchを使用できるようになり (詳細はSERVER-2238を参照)、必要な配列要素のみをプルバックできるようになりました。だから、次のようなことを試してください:

db.foo.find({"ID":"123",'a':{$elemMatch:{'x':"/"}}},{_id : 0, 'a.$': 1})
//returns
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }

または、プロジェクション自体で $elemMatch を使用するだけです。

db.foo.find({"ID":"123"},{_id : 0, 'a':{$elemMatch:{'x':"/"}}})
//returns 
{ "a" : [ { "x" : "/", "y" : "2000", "z" : "1000" } ] }

したがって、少なくとも返される配列は、必要なエントリのみを含む配列のみであり、関連する z 要素を参照するだけです (サブドキュメントの elemMatch プロジェクションはまだサポートされていません)。

最後になりましたが、2.2 には集約フレームワークがあり、それができることの 1 つ ($project演算子を使用して、ドキュメントを再形成し、サブドキュメントと配列要素をトップレベルの配列に変更することです。目的の結果を得るには、次のようなことをします:

db.foo.aggregate( 
        {$match : {"ID":"123"}},  
        {$unwind : "$a"},  
        {$match : {"a.x":"/"}},  
        {$project : {_id : 0, z : "$a.z"}}
)

結果は次のようになります。

{ "result" : [ { "z" : "1000" } ], "ok" : 1 }
于 2012-08-27T11:10:35.200 に答える