与えられたデータ:
> 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" }
parametersテーブル内の指定されたドキュメントのgroups配列内にあるすべてのグループをクエリが返すようにするparameters _idを指定します。
簡単な解決策は、PyMongoでいくつかのDB呼び出しを行うようです:
しかし、これには非常に多くの不必要なオーバーヘッドがあります。 (DBでカスタムJSを実行せずに)MongoDB内でこれを行うには、より良い、より高速な方法が必要だと思います。または、ドキュメントベースのアプローチを無視して、データを少し(正規化の表のように)正規化して再構成する必要がありますか?
繰り返しますが、PyMongo DBインターフェースから機能するソリューションを見つけるのを手伝ってください
これは、集計フレームワークを使用して単一のクエリ内で実行できます。特に、左結合を行うには$lookup
演算子を使用する集約パイプラインを実行する必要がありますparameters
コレクションからgroups
コレクションへ。
次のパイプラインの実行を検討してください。
db.parameters.aggregate([
{ "$unwind": "$groups" },
{
"$lookup": {
"from": "groups",
"localField": "groups",
"foreignField": "_id",
"as": "grp"
}
},
{ "$unwind": "$grp" }
])
出力例
/* 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"
}
}
MongoDBサーバーのバージョンが$lookup
パイプライン演算子をサポートしていない場合は、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 } })
編集:集計クエリのフィールド名をサンプルデータセットのフィールド名に一致させました(質問内)