根据question的答案,不保证对象的属性顺序。那么当我们将多个排序字段作为对象传递时,sort函数如何在MongoDB中完美地工作?
db.users.find({}).sort({firstName: 1, age:-1}).exec(callback);
mongodb如何知道它首先必须按firstName排序然后按年龄排序?这是错误的假设吗?
答案 0 :(得分:10)
这是一个有趣的问题。
它适用于大多数ECMAScript实现实际上执行保留密钥顺序(例如,Node使用的V8)。但是,官方Node MongoDB driver并不鼓励使用它,而是提供两种不同的符号:
可以使用带有数组的选项参数sort来进行排序 排序首选项
{ "sort": [['field1','asc'], ['field2','desc']] }
使用单个升序字段,可以使用字段名称替换数组。
{ "sort": "name" }
Mongoose文档没有提到任何关于密钥顺序的信息(至少不是我所知道的)。但它也提供two different approaches to sorting:
// sort by "field" ascending and "test" descending query.sort({ field: 'asc', test: -1 }); // equivalent query.sort('field -test');
事实上,似乎Mongoose排序功能基于错误(但目前有效)的假设。在使用多个键进行排序时,最好使用字符串表示法。 直接使用MongoDB时(例如在MongoDB shell中)使用对象表示法排序可正常工作,因为它不使用纯JSON而是使用extended JSON。
另请参阅此相关问题:How can you specify the order of properties in a javascript object for a MongoDB index in node.js?
还有一个Mongoose issue:
是的,对于猫鼬和mongodb来说,这是一个不幸的困境 驱动程序。 ECMAScript说密钥没有订购,但它们是 实际上是在V8中订购的(数字键除外,这是一个讨厌的边缘 案例),可能会继续在V8中订购 可预见的未来。 您可以使用[['field1','asc']]语法或 特定于猫鼬的'field1 -field2'语法或ES2015 Map类 (如果你担心的话,它保证了钥匙的插入顺序) 关键订单。
因此,在使用Mongoose时,请使用字符串表示法或新添加的ES2015 Maps支持,这些支持保证按插入顺序排序。
答案 1 :(得分:1)
在您的示例中,您使用MongoDB中的排序操作索引,如果您使用多个字段排序,则可以创建复合索引以支持对多个字段进行排序。正如您提供索引时所做的那样,查询计划程序从索引(您的示例的顺序:firstname,lastname)获取排序顺序,它将按您的订单排序。在另一个例子中,它是一个javascript对象。 Javascript不保证排序。