Dette er "by design" af $lookup
implementering. Hvad faktisk sker "under emhætten" er MongoDB intern konverterer argumenterne i $lookup
til det nye ekspressive formatere ved hjælp af $expr
og $in
. Selv i versioner før, da dette ekspressive form blev implementeret, den interne mekanik for en "matrix af værdier" var egentlig meget det samme.
Løsningen her er at vedligeholde en kopi af det originale array som reference til omarrangering af "joined" elementer:
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"
}}
])
Eller ved den gamle $lookup
brug:
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" }
}}
])
Begge varianter producerer det samme 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"
}
]
}
Det generelle koncept er at bruge $indexOfArray
sammenlignet med _id
værdi fra "tilsluttet" indhold for at finde det "indeks" position i det originale kildearray fra "$Classes.ID"
. De forskellige $lookup
syntaksvarianter har forskellige tilgange til, hvordan du får adgang til denne kopi og hvordan du grundlæggende rekonstruerer.
$sort
angiver selvfølgelig rækkefølgen af faktiske dokumenter, enten inde i pipeline-behandlingen for den ekspressive form eller via de synlige dokumenter fra $unwind
. Hvor du brugte $unwind
du ville derefter $group
tilbage til den originale dokumentformular.
BEMÆRK :Brugseksemplerne her afhænger af MongoDB 3.4 for $indexOfArray
i det mindste og $$REMOVE
justeres med MongoDB 3.6, ligesom ekspressive $lookup
.
Der er andre metoder til at genbestille arrayet til tidligere udgivelser, men disse er demonstreret mere detaljeret på Does MongoDB's $in-klausul-garantiordre. Realistisk set er det absolut minimum, du i øjeblikket bør køre som en produktionsversion af MongoDB, 3.4-udgivelsen.
Se Supportpolitik under MongoDB Server for alle detaljer om understøttede udgivelser og slutdatoer.