I'm trying to get the "top" 2 items for any number of foreign keys, sorted by some key. What I have is the following, which appears to work:

    {$match: {fk: {$in: [1, 2]}}}
    {$sort: {name: -1}}, 
    {$group: {_id: "$fk", items: {$push: "$$ROOT"} }}, 
    {$project: {items: {$slice: ["$items", 2]} }}

My question is: does MongoDB guarantee that the sorting I apply in the second step in my aggregation via $sort will be maintained when I get down to the $slice inside my $project in the last step of my aggregation?

The data I'm seeing indicates that MongoDB is currently behaving this way, but I'm wondering if this is spec'd or if MongoDB is free to return the items array in a different order if the optimizer ever decides it would be advantageous to do so.


Your conclusion is correct: internal optimisations or implementation details may alter the order of results depending on the stage.

The $group stage is intentionally not order preserving, so you cannot rely on observational behaviour.

As noted in discussion on SERVER-24799: $group aggregation command should maintain document order in the MongoDB issue tracker:

The reason the order is not preserved is that we keep track of all groups with a map from the _id to the accumulated value, so that we can quickly look up which group an incoming document belongs to.

As per Aggregation Pipeline Optimizations, some pipeline stages may also be coalesced or reordered to equivalent pipelines with improved performance. You can use the explain:true option to return information about how a pipeline will be executed.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.