The query returns the order in which elements are placed in their collection, ignoring the order of the initial array. This affects the function of our system. Is there any extra command to put it in the correct order? Is there any workaround available?
Here follows a simple example:
Collection1 Document
{
"_id":ObjectId("5c781752176c512f180048e3"),
"Name":"Pedro",
"Classes":[
{"ID": ObjectId("5c7af2b2f6f6e47c9060d7ce") },
{"ID": ObjectId("5c7af2bcf6f6e47c9060d7cf") },
{"ID": ObjectId("5c7af2aaf6f6e47c9060d7cd") }
]
}
Collection2 Documents
{
"_id":ObjectId("5c7af2aaf6f6e47c9060d7cd"),
"variable1":"A"
},
{
"_id": ObjectId("5c7af2b2f6f6e47c9060d7ce"),
"variable1":"B"
},
{
"_id": ObjectId("5c7af2bcf6f6e47c9060d7cf"),
"variable1":"C"
}
The query:
aggregate(
pipeline = '[
{"$match": {"_id": {"$oid": "5c781752176c512f180048e3"}}},
{"$lookup": {"from": "collection2", "localField": "Classes.ID", "foreignField": "_id", "as": "Collection2_doc"}}
]'
)
Returns:
Result's order:
[
{
"_id":ObjectId("5c7af2aaf6f6e47c9060d7cd"),
"variable1":"A"
},
{
"_id": ObjectId("5c7af2b2f6f6e47c9060d7ce"),
"variable1":"B"
},
{
"_id": ObjectId("5c7af2bcf6f6e47c9060d7cf"),
"variable1":"C"
}
]
Expected order (first document array order):
[
{
"_id": ObjectId("5c7af2b2f6f6e47c9060d7ce"),
"variable1":"B"
},
{
"_id": ObjectId("5c7af2bcf6f6e47c9060d7cf"),
"variable1":"C"
},
{
"_id":ObjectId("5c7af2aaf6f6e47c9060d7cd"),
"variable1":"A"
}
]
Are there any extra command ex. $sort
that could be used to return it respecting the original arrays order?
This is "by design" of the
$lookup
implementation. What actually happens "under the hood" is MongoDB internall converts the arguments in the$lookup
to the new expressive format using$expr
and$in
. Even in versions prior to when this expressive form was implemented, the internal mechanics for an "array of values" was really much the same.The solution here is to maintain a copy of the original array as a reference for reordering the "joined" items:
Or by the legacy
$lookup
usage:Both variants produce the same output:
The general concept being to use
$indexOfArray
in comparison with the_id
value from the "joined" content to find it's "index" position in the original source array from"$Classes.ID"
. The different$lookup
syntax variants have different approaches to how you access this copy and how you basically reconstruct.The
$sort
of course sets the order of actual documents, either being inside the pipeline processing for the expressive form, or via the exposed documents of$unwind
. Where you used$unwind
you would then$group
back to the original document form.