基本的に、 $unwind
を実行する必要があります。
最初にアレイ。 MongoDBは、配列内のオブジェクトの「内部」プロパティを $lookup
。
また、効率を上げるために、実際には $concatArrays
を使用する必要があります。
最初にアレイソースを「結合」し、次に1つだけ実行します $lookup
操作:
Project.aggregate([
{ "$match": { "project_id": projectId} },
{ "$project": {
"project_id": 1,
"updated_at": 1,
"created_at": 1,
"owner": 1,
"name": 1,
"combined": {
"$concatArrays": [
{ "$map": {
"input": {
"$filter": {
"input": "$uploaded_files",
"as": "uf",
"cond": { "$eq": ["$$uf.upload_id", uploadId ] }
}
},
"as": "uf",
"in": {
"$arrayToObject": {
"$concatArrays": [
{ "$objectToArray": "$$uf" },
[{ "k": "type", "v": "uploaded_files" }]
]
}
}
}},
{ "$map": {
"input": {
"$filter": {
"input": "$file_history",
"as": "fh",
"cond": { "$eq": ["$$fh.upload_id", uploadId ] }
}
},
"as": "fh",
"in": {
"$arrayToObject": {
"$concatArrays": [
{ "$objectToArray": "$$fh" },
[{ "k": "type", "v": "file_history" }]
]
}
}
}}
]
}
}},
{ "$unwind": "$combined" },
{ "$lookup": {
"from": "files",
"localField": "combined.file",
"foreignField": "_id",
"as": "combined.file"
}},
{ "$unwind": "$combined.file" },
{ "$lookup": {
"from": "users",
"localField": "owner",
"foreignField": "_id",
"as": "owner"
}},
{ "$unwind": "$owner" },
{ "$group": {
"_id": "$_id",
"project_id": { "$first": "$project_id" },
"updated_at": { "$first": "$updated_at" },
"created_at": { "$first": "$created_at" },
"owner": { "$first": "$owner" },
"name": { "$first": "$name" },
"combined": { "$push": "$combined" }
}},
{ "$project": {
"project_id": 1,
"updated_at": 1,
"created_at": 1,
"owner": 1,
"name": 1,
"uploaded_files": {
"$filter": {
"input": "$combined",
"as": "cf",
"cond": { "$eq": [ "$$cf.type", "uploaded_files" ] }
}
},
"file_history": {
"$filter": {
"input": "$combined",
"as": "cf",
"cond": { "$eq": [ "$$cf.type", "file_history" ] }
}
}
}}
])
一言で言えば
-
2つのアレイをソースにまとめてタグを付けてから、
$unwind
最初 -
$lookup
を実行します 詳細と$unwind
それ -
$lookup
を実行します 他の外国のソースと$unwind
それ -
$group
ドキュメントを単一の配列と一緒に戻します。 -
$filter
配列を「分離」するために追加した「タグ名」または「タイプ」フィールドによって。
$unwind
を使用するだけで、同じ種類のプロセスに従うことができます。 各アレイで、「結合」を実行し、グループ化して戻します。しかし、実際には、そもそも単に「組み合わせる」よりも、はるかに多くのステップが必要です。