Finally found the source of an annoying bug in our pipelines. When using a $sort stage in an aggregation, if there are multiple fields to sort on, put them into separate sort stages! Go does not guarantee the return order of map keys, so when I had a sort stage like this:
{{"$sort", bson.M{
"lastName": 1,
"firstName": 1,
}}},
it was not guaranteed that these fields would remain in this order - finally figured out why sometimes our sorting was not correct, when I noticed this stage in a log:
{
"$sort": {
"firstName": 1,
"lastName": 1
}
}
The sort order has been switched around, because Go iterates over maps from a random key position.
If you are using Go and need a sort stage with multiple fields, break it into separate sorts in the reverse order:
{{"$sort", bson.M{
"firstName": 1,
}}},
{{"$sort", bson.M{
"lastName": 1,
}}},
gives the desired output of sorting by lastName, firstName.
Haven’t tested it because I don’t use this format, but using bson.D would probably work as a single stage too.
{{"$sort", bson.D{
"lastName", 1,
"firstName", 1,
}}},