Fondamentalmente devi $unwind
prima la matrice. MongoDB non può ancora funzionare con la proprietà "inner" di un oggetto all'interno di un array come sorgente per $lookup
.
Anche per efficienza dovremmo davvero usare $concatArrays
prima di "unire" l'origine dell'array, quindi eseguirne solo uno $lookup
operazione:
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" ] }
}
}
}}
])
In poche parole
-
Riunisci i due array sul sorgente e taggali, quindi
$unwind
prima -
$group
il documento di nuovo insieme con un singolo array. -
$filter
dal campo "nomi dei tag" o "tipo" abbiamo aggiunto per "separare" gli array.
Puoi seguire lo stesso tipo di processo semplicemente usando $unwind
su ogni array, quindi eseguire il "join" e raggruppare di nuovo insieme. Ma in realtà ciò richiede molti più passaggi, rispetto alla semplice "combinazione" in primo luogo.