As per the answer to the question, the order of properties on an object is not guaranteed. Then how does the sort function work flawlessly in MongoDB when we pass multiple s
In your example you use indexes for sort operations in MongoDB and if you sort with multiple fields you create a compound index to support sorting on multiple fields. As you did when you give indexes, the query planner obtain the sort order from your indexes (your example's order: firstname, lastname) and it will sort by your order. In the other example it is a javascript object. Javascript doesn't warrant sorting.
This is an interesting question.
It works as most ECMAScript implementations actually do preserve the key order (e.g. V8 which is used by Node). However, the official Node MongoDB driver does not encourage its use, instead it offers two different notations:
Sorting can be acieved with option parameter sort which takes an array of sort preferences
{ "sort": [['field1','asc'], ['field2','desc']] }
With single ascending field the array can be replaced with the name of the field.
{ "sort": "name" }
The Mongoose documentation does not mention anything regarding key order (at least not that I know of). But it also offers two different approaches to sorting:
// sort by "field" ascending and "test" descending query.sort({ field: 'asc', test: -1 }); // equivalent query.sort('field -test');
Indeed it seems that the Mongoose sort functionality was based on wrong (but currently valid) assumption. It is probably best if you use the string notation when sorting with multiple keys. Sorting with the object notation works properly when using MongoDB directly (e.g. in the MongoDB shell) as it does not use pure JSON but extended JSON.
Also see this very related question: How can you specify the order of properties in a javascript object for a MongoDB index in node.js?
There is also a Mongoose issue about this:
Yep, that's an unfortunate dilemma for both mongoose and the mongodb driver. ECMAScript says that keys are not ordered, but they are actually ordered in V8 (except for numeric keys, which is a nasty edge case), and likely will continue to be ordered in V8 for the foreseeable future. You can use the [['field1', 'asc']] syntax or the mongoose-specific 'field1 -field2' syntax or the ES2015 Map class (which guarantees insertion order for keys) if you're concerned with key order.
So when using Mongoose, either use the string notation or the newly added support for ES2015 Maps which are guaranteed to be ordered by insertion order.