Jest to "zgodnie z projektem" $lookup
realizacja. Co faktycznie dzieje się „pod maską” czy MongoDB jest wewnętrzny konwertuje argumenty w $lookup
do nowej ekspresji sformatuj za pomocą $expr
i $in
. Nawet w wersjach wcześniejszych niż to ekspresyjne zaimplementowano formularz, wewnętrzna mechanika "tablicy wartości" był naprawdę taki sam.
Rozwiązaniem tutaj jest zachowanie kopii oryginalnej tablicy jako odniesienia do zmiany kolejności "dołączonych" przedmioty:
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"
}}
])
Lub starszego $lookup
użycie:
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" }
}}
])
Oba warianty dają ten sam wynik:
{
"_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"
}
]
}
Ogólna koncepcja polega na użyciu $indexOfArray
w porównaniu z _id
wartość z „dołączonych” zawartość, aby znaleźć to jest "indeks" pozycja w oryginalnej tablicy źródłowej z "$Classes.ID"
. Różne $lookup
warianty składni mają różne podejścia do uzyskiwania dostępu do tej kopii i jak w zasadzie rekonstruujesz.
$sort
oczywiście ustala kolejność rzeczywistych dokumentów, które są w ramach przetwarzania potoku dla formy ekspresyjnej lub poprzez ujawnione dokumenty $unwind
. Gdzie użyłeś $unwind
wtedy $group
z powrotem do oryginalnego formularza dokumentu.
UWAGA :Przykłady użycia tutaj zależą od MongoDB 3.4 dla $indexOfArray
przynajmniej i $$REMOVE
jest zgodny z MongoDB 3.6, podobnie jak ekspresyjny $lookup
.
Istnieją inne podejścia do zmiany kolejności tablicy we wcześniejszych wydaniach, ale są one przedstawione bardziej szczegółowo w kolejności gwarancji klauzuli $in w Czy MongoDB. Realistycznie absolutnym minimum, które powinieneś obecnie używać jako produkcyjnej wersji MongoDB, jest wydanie 3.4.
Zobacz Zasady pomocy technicznej pod Serwerem MongoDB aby uzyskać szczegółowe informacje o obsługiwanych wydaniach i datach zakończenia.