Grundsätzlich müssen Sie $unwind
das Array zuerst. MongoDB kann noch nicht mit der „inneren“ Eigenschaft eines Objekts innerhalb eines Arrays als Quelle für $lookup
.
Auch aus Effizienzgründen sollten wir wirklich $concatArrays
verwenden
zuerst der Array-Quelle "beitreten" und dann nur eine ausführen $lookup
Betrieb:
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" ] }
}
}
}}
])
Kurz gesagt
-
Bringen Sie die beiden Arrays in der Quelle zusammen und markieren Sie sie, dann
$unwind
zuerst -
Führen Sie
$lookup
durch auf den kombinierten Details und$unwind
das -
Führen Sie
$lookup
durch auf der anderen Fremdquelle und$unwind
das -
$group
das Dokument wieder zusammen mit einem einzigen Array. -
$filter
durch das Feld "Tag-Namen" oder "Typ", das wir hinzugefügt haben, um die Arrays zu "trennen".
Sie können dem gleichen Prozess folgen, indem Sie einfach $unwind
verwenden auf jedem Array, dann "verbinden" und wieder zusammen gruppieren. Aber das braucht wirklich viel mehr Schritte, als überhaupt erst "kombinieren".