2016-10-28 4 views
2

がデータを考えると、単純なサブクエリ例:のMongoDB -

> db.parameters.find({}) 
{ "_id" : ObjectId("56cac0cd0b5a1ffab1bd6c12"), "name" : "Speed", "groups" : [ " 
123", "234" ] } 
> db.groups.find({}) 
{ "_id" : "123", "name" : "Group01" } 
{ "_id" : "234", "name" : "Group02" } 
{ "_id" : "567", "name" : "Group03" } 

私はクエリがグループ内で与えられた文書のアレイに含まれるすべてのグループを返すよう_id パラメータを供給したいと思いますパラメータテーブル。

簡単な解決策は、複数のDBがPyMongoに呼び出しを行うようだ:

  1. グループ配列の各要素について
  2. _id供給に基づいてパラメータテーブルからパラメータを取得しますからドキュメントを選択グループコレクション

しかし、これは非常に多くの不要なオーバーヘッドを持ちます。私はMongoDB内でこれを行うために(DB内でカスタムJSを実行することなく)、これを行うためのより良い、より速い方法が必要であると感じています。あるいは、文書ベースのアプローチを無視して、データを少しでも正規化して(リレーションシップのテーブルのように)データを再構成する必要がありますか?

再び、私はあなたが集約フレームワークを使用して単一のクエリ内でこれを行うことができますPyMongo DBインタフェース

答えて

5

からうまくいく解決策を見つける助けてください。特に、parametersコレクションからgroupsコレクションへの左結合を行うには、$lookup演算子を使用する集計パイプラインを実行する必要があります。あなたのMongoDBサーバのバージョンは、あなたがしたい、$lookupパイプライン演算子をサポートしていない場合の出力例

/* 1 */ 
{ 
    "_id" : ObjectId("56cac0cd0b5a1ffab1bd6c12"), 
    "name" : "Speed", 
    "groups" : "123", 
    "grp" : { 
     "_id" : "123", 
     "name" : "Group01" 
    } 
} 

/* 2 */ 
{ 
    "_id" : ObjectId("56cac0cd0b5a1ffab1bd6c12"), 
    "name" : "Speed", 
    "groups" : "234", 
    "grp" : { 
     "_id" : "234", 
     "name" : "Group02" 
    } 
} 

db.parameters.aggregate([ 
    { "$unwind": "$groups" }, 
    { 
     "$lookup": { 
      "from": "groups", 
      "localField": "groups", 
      "foreignField": "_id", 
      "as": "grp" 
     } 
    }, 
    { "$unwind": "$grp" } 
]) 

は、次のパイプラインを実行している考えてみましょう次のように2つのクエリを実行する必要があります。

# get the group ids 
ids = db.parameters.find_one({ "_id": ObjectId("56cac0cd0b5a1ffab1bd6c12") })["groups"] 

# query the groups collection with the ids from previous query 
db.groups.find({ "_id": { "$in": ids } }) 

EDIT:(質問以内)例データセット内のフィールド名に集約クエリでフィールド名を一致