Mongodbは、ネストされたルックアップを含む複雑なドキュメントを集約します
Aug 19 2020
私はこれらのコレクションを持っています:
サイト
{
_id: ObjectId("5acdb8f65ea63a27c1facf86"),
TemplateId: ObjectId("sdfsdfs34234234sdf"),
}
テンプレート
{
_id: ObjectId("sdfsdfs34234234sdf"),
Type: "Site",
Name: "Site 1",
Sections:[{
id: ObjectId("8asdf89asd8f9sdf"),
Header: "Header1",
FieldItems: [
{
FieldId: ObjectId("jsd32423423423"),
x: 1,
y: 0
},
{
FieldId: ObjectId("2342sdffafdasdfdfs"),
x: 1,
y: 1
}
]
},
(...more sections...)
]
}
田畑
{
_id: ObjectId("jsd32423423423"),
Type: "Phone",
Name: "Phone_Test"
},
{
_id: ObjectId("2342sdffafdasdfdfs"),
Type: "Numeric",
Name: "Number_Test"
}
私はMongoDBを初めて使用しますが、質問と回答、およびドキュメントを読むのに数日かかりました。MongoDB4.2.6を使用しています。次のような形式の結果を返そうとしています。
{
id: ObjectId("5acdb8f65ea63a27c1facf86"),
TemplateId: ObjectId("sdfsdfs34234234sdf"),
Template: {
id: ObjectId("sdfsdfs34234234sdf"),
Type: "Site",
Sections:[{
id: ObjectId("8asdf89asd8f9sdf"),
Header: "Header1",
FieldItems: [
{
FieldId: ObjectId("jsd32423423423"),
x: 1,
y: 0,
Field: {
_id: ObjectId("jsd32423423423"),
Type: "Phone",
Name: "Phone_Test"
}
}, (...)]
}]
}
ネストされたルックアップを使用して集計クエリを作成し、ほとんどの場所にアクセスできるようにしましたが、それを機能させるには、SectionsとFieldItemsをアンワインドする必要がありました。配列を希望どおりに配置する方法がわかりません。グループを試しましたが、サブ配列に問題があります。これが必要な結果を得る最良の方法であるかどうかさえわかりません。
db.getCollection("AppSites").aggregate(
[
{
"$lookup" : { "from" : "AppTemplates", "let": {"template_id": "$TemplateId"},
"pipeline": [
{ "$match": { "$expr": { "$eq" : ["$_id", "$$template_id"] } } }, { "$unwind": "$Sections"}, { "$unwind": "$Sections.FieldItems"}, { "$lookup": {
"from": "AppFields",
"let": {"field_id": "$Sections.FieldItems.FieldId"}, "pipeline": [ { "$match": { "$expr": { "$eq": ["$_id", "$$field_id"] } } }
],
"as": "Sections.FieldItems.Field"
}
}
],
"as" : "Templates"
}
}
]
);
回答
1 varman Aug 19 2020 at 00:21
あなたは$unwind
2回行ったので、2回使用する必要があります$group
。
{
$group: { _id: { secId: "$_id",
fId: "$Sections.id" }, Type: { $first: "$Type" }, Name: { $first: "$Name" }, Header: { $first: "$Sections.Header" }, fieldItems: { $push: "$Sections.FieldItems" } } }, { $group: {
_id: "$_id.secId", Type: { $first: "$Type" }, Name: { $first: "$Name" }, Sections: { $push: {
id: "$_id.fId", Header: "$Header",
fieldItems: "$fieldItems"
}
}
}
}
- 最初のグループ-子オブジェクトをグループ化します。ただし、Type、Name、Headerはそれぞれ親配列と子配列に設定する必要があります。
- 2番目のグループ-親オブジェクトをグループ化します。子をグループ化するときに、すべてのスタンドアロンフィールドを取得します。ここでは、正しい鉱石に設定する必要があります。
働くモンゴの遊び場
注:を使用$lookup
すると、配列が提供されます。しかし、オブジェクトとして作成する場所がいくつかあります。あなたが1対1の関係で参加しているかどうかはわかりません。その場合、射影またはarrayElemAtで位置演算子を使用できます