[SERVER-30385] Lookup an array ob ObjectId doesn't guaranty the order Created: 28/Jul/17 Updated: 27/Oct/23 Resolved: 07/Aug/17 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Aggregation Framework |
| Affects Version/s: | 3.4.4 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | CAO Quang Binh | Assignee: | Mark Agarunov |
| Resolution: | Works as Designed | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Operating System: | ALL |
| Participants: |
| Description |
|
I have 2 collections:
`bars` is the array of `Bar`'s ObjectId. I would like to use `lookup` to get the array of `Bar` in EXACTLY order that the Id stored in `bars`.
Everything are ok, UNTIL I $push another Bar's ObjectId to BEGIN of the `bars` array. The $lookup will returns the array which the new one is in the end of array, NOT begin of array as my expectation. For example:
=> A, B
=> A, B, C My expectation is: A, B, C, D. |
| Comments |
| Comment by Asya Kamsky [ 29/Jul/19 ] | ||||||||||||||||
|
The workaround can be similar to the one described here which is to use original array and $map to get the order matching original array. This avoids $unwind and $group which is desirable as $group is a blocking stage and will slow things down most likely. | ||||||||||||||||
| Comment by CAO Quang Binh [ 07/Aug/17 ] | ||||||||||||||||
|
Hi @Charlie Swanson, Thank you for your reply. Your solution is the same as the one I describe above. So, I'll consider this is the "official solution" for my purpose. | ||||||||||||||||
| Comment by Charlie Swanson [ 01/Aug/17 ] | ||||||||||||||||
|
Hi binh.cao, Note that we do not guarantee anything about the order of results coming back from the $lookup. If you require them to be in a particular order, you must sort them yourself. This lookup is the equivalent of doing a $in query with each of the values in 'data.users', which would not provide any ordering either. One way you could do this is to do the following:
| ||||||||||||||||
| Comment by CAO Quang Binh [ 01/Aug/17 ] | ||||||||||||||||
|
Hi @Mark Agarunov,
And the $lookup:
If you need any infomation, just tell me, I'll give it to you. | ||||||||||||||||
| Comment by Mark Agarunov [ 31/Jul/17 ] | ||||||||||||||||
|
Hello binh.cao, Thank you for the information. If possible please provide the exact queries you are using, including the $push query being used so that we can reproduce this exactly the same way. Thank you, | ||||||||||||||||
| Comment by CAO Quang Binh [ 29/Jul/17 ] | ||||||||||||||||
|
Hi @Mark Agarunov, I did use the $position modifier. As I described, I $push the C_id to the BEGIN of bars field. In the db, I got this order: C_id, A_id, B_id. However, after $lookup, I got: A, B, C. C is still in the END of line, although in db, it's in the BEGIN of line. p/s: my current solution is:
However, I still need the official solution: the order after the lookup is exactly the same as the order in db. | ||||||||||||||||
| Comment by Mark Agarunov [ 28/Jul/17 ] | ||||||||||||||||
|
Hello binh.cao, Thank you for the report. Looking over the behavior you've described, I suspect this may be due to the $push operator. Are you using the $position modifier for the $push operator? From the documentation for $push:
Thanks, | ||||||||||||||||
| Comment by CAO Quang Binh [ 28/Jul/17 ] | ||||||||||||||||
|
UPDATE: P/s: I don't know how to edit my description. |