Questo è "in base alla progettazione" di $lookup
implementazione. Cosa in realtà succede "sotto il cofano" è MongoDB interno converte gli argomenti nel $lookup
al nuovo espressivo formattare utilizzando $expr
e $in
. Anche nelle versioni precedenti a quando questo espressivo modulo è stato implementato, la meccanica interna per un "array di valori" era davvero lo stesso.
La soluzione qui è mantenere una copia dell'array originale come riferimento per riordinare il "unito" articoli:
collection.aggregate([
{"$match": {"_id": ObjectId("5c781752176c512f180048e3") }},
{"$lookup": {
"from": "collection2",
"let": { "classIds": "$Classes.ID" },
"pipeline": [
{ "$match": {
"$expr": { "$in": [ "$_id", "$$classIds" ] }
}},
{ "$addFields": {
"sort": {
"$indexOfArray": [ "$$classIds", "$_id" ]
}
}},
{ "$sort": { "sort": 1 } },
{ "$addFields": { "sort": "$$REMOVE" }}
],
"as": "results"
}}
])
O dall'eredità $lookup
utilizzo:
collection.aggregate([
{"$match": {"_id": ObjectId("5c781752176c512f180048e3") }},
{"$lookup": {
"from": "collection2",
"localField": "Classes.ID",
"foreignField": "_id",
"as": "results"
}},
{ "$unwind": "$results" },
{ "$addFields": {
"sort": {
"$indexOfArray": [ "$Classes.ID", "$results._id" ]
}
}},
{ "$sort": { "_id": 1, "sort": 1 } },
{ "$group": {
"_id": "$_id",
"Name": { "$first": "$Name" },
"Classes": { "$first": "$Classes" },
"results": { "$push": "$results" }
}}
])
Entrambe le varianti producono lo stesso output:
{
"_id" : ObjectId("5c781752176c512f180048e3"),
"Name" : "Pedro",
"Classes" : [
{
"ID" : ObjectId("5c7af2b2f6f6e47c9060d7ce")
},
{
"ID" : ObjectId("5c7af2bcf6f6e47c9060d7cf")
},
{
"ID" : ObjectId("5c7af2aaf6f6e47c9060d7cd")
}
],
"results" : [
{
"_id" : ObjectId("5c7af2b2f6f6e47c9060d7ce"),
"variable1" : "B"
},
{
"_id" : ObjectId("5c7af2bcf6f6e47c9060d7cf"),
"variable1" : "C"
},
{
"_id" : ObjectId("5c7af2aaf6f6e47c9060d7cd"),
"variable1" : "A"
}
]
}
Il concetto generale è usare $indexOfArray
rispetto a _id
valore da "unito" contenuto per trovarlo è "indice" posizione nell'array di origine originale da "$Classes.ID"
. Il diverso $lookup
le varianti di sintassi hanno approcci diversi al modo in cui accedi a questa copia e come sostanzialmente ricostruisci.
Il $sort
ovviamente imposta l'ordine dei documenti effettivi, essendo all'interno dell'elaborazione della pipeline per la forma espressiva, o tramite i documenti esposti di $unwind
. Dove hai usato $unwind
quindi $group
torna al modulo del documento originale.
NOTA :Gli esempi di utilizzo qui dipendono da MongoDB 3.4 per $indexOfArray
almeno e il $$REMOVE
si allinea con MongoDB 3.6 come farebbe il espressivo $lookup
.
Esistono altri approcci per riordinare l'array per le versioni precedenti, ma questi sono dimostrati in modo più dettagliato nell'ordine di garanzia della clausola $in di Does MongoDB. Realisticamente il minimo indispensabile che dovresti attualmente eseguire come versione MongoDB di produzione è la versione 3.4.
Consulta le Norme di supporto in Server MongoDB per i dettagli completi delle versioni supportate e delle date di fine.