Това е "по дизайн" на $lookup
изпълнение. Какво всъщност се случва "под капака" е MongoDB вътрешен преобразува аргументите в $lookup
към новия изразителен форматирайте с помощта на $expr
и $in
. Дори във версиите преди това изразително Формата е внедрена, вътрешната механика за "масив от стойности" беше наистина почти същото.
Решението тук е да поддържате копие на оригиналния масив като препратка за пренареждане на „joined“ елементи:
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"
}}
])
Или от наследения $lookup
употреба:
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" }
}}
])
И двата варианта произвеждат еднакъв изход:
{
"_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"
}
]
}
Общата концепция е да се използва $indexOfArray
в сравнение с _id
стойност от "joined" съдържание, за да откриете, че е „индекс“ позиция в оригиналния изходен масив от "$Classes.ID"
. Различният $lookup
вариантите на синтаксис имат различни подходи към начина, по който осъществявате достъп до това копие и как основно реконструирате.
$sort
разбира се задава реда на действителните документи, като в рамките на обработката на конвейера за изразителната форма или чрез откритите документи на $unwind
. Където сте използвали $unwind
тогава ще $group
обратно към оригиналния формуляр на документа.
ЗАБЕЛЕЖКА :Примерите за използване тук зависят от MongoDB 3.4 за
$indexOfArray
поне и$$REMOVE
подравнява се с MongoDB 3.6, както и изразителният$lookup
.Има и други подходи за пренареждане на масива за предишни издания, но те са демонстрирани по-подробно в поръчката за гаранция $in на клаузата на MongoDB. Реално минимумът, който в момента трябва да използвате като производствена версия на MongoDB, е версията 3.4.
Вижте Правила за поддръжка под MongoDB сървър за пълните подробности за поддържаните издания и крайни дати.