Ini adalah "sesuai desain" dari $lookup
penerapan. Apa sebenarnya terjadi "di bawah tenda" adalah MongoDB internal mengonversi argumen di $lookup
ke ekspresif yang baru format menggunakan $expr
dan $in
. Bahkan dalam versi sebelum ekspresif ini formulir diimplementasikan, mekanisme internal untuk "array nilai" benar-benar sama.
Solusinya di sini adalah menyimpan salinan larik asli sebagai referensi untuk menyusun ulang "bergabung" item:
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"
}}
])
Atau dengan $lookup
legacy yang lama penggunaan:
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" }
}}
])
Kedua varian menghasilkan output yang sama:
{
"_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"
}
]
}
Konsep umum adalah menggunakan $indexOfArray
dibandingkan dengan _id
nilai dari "bergabung" konten untuk menemukan "indeks" posisi dalam larik sumber asli dari "$Classes.ID"
. $lookup
different yang berbeda varian sintaks memiliki pendekatan yang berbeda tentang cara Anda mengakses salinan dan bagaimana Anda pada dasarnya merekonstruksi.
$sort
tentu saja mengatur urutan dokumen yang sebenarnya, baik yang di dalam pemrosesan pipa untuk bentuk ekspresif, atau melalui dokumen terbuka $unwind
. Tempat Anda menggunakan $unwind
Anda kemudian akan $group
kembali ke formulir dokumen asli.
CATATAN :Contoh penggunaan di sini bergantung pada MongoDB 3.4 untuk
$indexOfArray
setidaknya dan$$REMOVE
sejajar dengan MongoDB 3.6 seperti halnya ekspresif$lookup
.Ada pendekatan lain untuk mengurutkan ulang array untuk rilis sebelumnya, tetapi ini ditunjukkan secara lebih rinci pada pesanan jaminan klausa $in dari Apakah MongoDB. Secara realistis, minimum yang harus Anda jalankan saat ini sebagai versi produksi MongoDB adalah rilis 3.4.
Lihat Kebijakan Dukungan di bawah Server MongoDB untuk detail lengkap tentang rilis yang didukung dan tanggal akhir.