【问题标题】:MongoDB multiple sort properties: How is precedence determined?MongoDB 多重排序属性:如何确定优先级?
【发布时间】:2014-08-31 06:30:44
【问题描述】:

根据 Mongo 的文档,您可以像这样指定多个排序键:

{ $sort : { age : -1, posts: 1 } }

他们说首先按年龄(降序)然后按帖子(升序)排序。

但是排序查询是一个 Javascript 对象。据我所知,虽然实现通常会按照属性的创建顺序迭代属性,但这实际上并不是 ECMAScript 规范的一部分:对象属性正式没有顺序。

MongoDB 是否真的依赖于可能因实现而异的任意行为,我对 ECMAScript 规范是否有错误,或者我是否在 Mongo 文档中遗漏了一些可以让您以其他方式调整优先级的内容?

【问题讨论】:

    标签: javascript mongodb ecmascript-5


    【解决方案1】:

    控制台很特殊,它的对象实际上是按不同于普通 EMCAscript 的顺序排列的,所以这可能会发生。

    这是来自 10gen 员工的一个链接问题:https://stackoverflow.com/a/18514551/383478

    除其他外,字段的顺序始终保持不变。

    N.B:值得注意的是,V8(从 v2.2 开始运行 MongoDB shell 和 MR)在实践中已经对对象进行了排序。

    在非 V8 JS 中保持秩序的唯一真正方法是进行关键查找,例如:How to keep an Javascript object/array ordered while also maintaining key lookups?

    【讨论】:

    • 谢谢,Sammaye。我应该更清楚地提出这个问题:我知道它会因为 V8 而工作,但我问题的主旨不是“它会工作吗?”它是“这就是它的实施方式吗?”我认为可能有一些更明确的方式来声明序列。 10gen 的答案很好地总结了 Neil 所说的话,除了它承认 V8 之外的 JS 可能表现不一样,这就是让我觉得这很奇怪的原因(我有时会有来自客户端的查询——所以它是 JS/ JSON 端到端,但我不能 100% 确定保留了属性顺序)。
    • @Semicolon 可以吗?他说 EMCAScript 按规格订购,但我说外壳是特殊的。他说控制台实际上是用 BSON 编写的,这也是不正确的,你是对的,它是 EMCAScript,V8 变体。在我看来完全不同,但没关系。如果您有来自 node.js 的查询,它们将被排序,但如果您有来自浏览器的查询,则无法保证顺序。
    • @Semicolon 我想你可以做一个键查找来保持浏览器中的顺序:stackoverflow.com/questions/5773950/… 这也可以让你声明与不同查询不同的序列
    • 嗯,无论如何,他的主要观点,据我所知,我猜这“不应该是一个问题”?我对 BSON 位感到困惑,但在这一点上不是 100% 确定的。在进行研究时,我惊讶地发现浏览器在其实现中的差异有多大:stackoverflow.com/a/8704349/1631952。我现在的解决方案是将浏览器中的排序参数作为数组传递并创建排序对象服务器端。 (如果您想稍微调整答案以说明属性序列是指定优先级的唯一方法,我将继续并将其标记为已接受。)
    • @Semicolon V8 很特殊,它在允许有序对象方面违反规范,目前仅在 Opera 和 chrome 中实现。嗯,这个答案说蜘蛛猴现在也保持秩序,众所周知,Firefox 会复制谷歌,所以也许......
    【解决方案2】:

    是的,您对 ECMAScript 规范有误。属性保留它们的顺序,这就是为什么某些语言驱动程序(例如 Perl 默认按键名排序“哈希”,使用 Tie::IxHash 来更改它)推荐的形式也保持要转换的结构中的顺序。

    无论如何,这不是“真正的”JavaScript,而是 BSON。无论如何,它是借用的行为,因此该声明实际上保持不变。您指定的顺序将被保留。

    【讨论】:

    • 截至 2011 年,规范明确表示对象属性没有顺序。您是否有指向后续版本的链接?另外,我很确定 Mongo 运行 V8 ...文档存储在 BSON 中(这是一种数据格式,而不是执行上下文...?),但查询在 V8 (Javascipt) 中执行。
    • ECMA-262 似乎是最新的。那就是我发现它指出没有保证的顺序的地方。不过,我还没有检查 Harmony。 FWIW,JSON 规范还说对象属性没有保证顺序,并且 BSON 是 JSON 派生词(这并不意味着它不会改变这种行为,但这似乎非常一致)。
    • @Semicolon 订单将始终按指定保留。正如我所说,在其他语言中,在某些情况下,可翻译结构通常默认按其他方式排序,您需要应用一些方法来确保保留顺序。但我不知道这适用于 JavaScript、JSON 或 BSON。所以无论你在读什么似乎都是不正确的。
    • 我正在阅读 ECMAScript 规范。确实,V8 和除某些版本的 IE 之外的所有浏览器都保留了序列,但这是未指定的行为(显然 V8 的早期版本也没有保留序列)。不管是不是事实上,Mongo 会依赖它让我感到奇怪。 stackoverflow.com/questions/5525795/…
    • @Semicolon 我所说的是产生一个我所说的不正确的情况,然后你有自己的答案。如果你不能,那么我说的是真的。这基本上就是我们解决问题的方式。反驳一个陈述或证明它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多