【问题标题】:Does MongoDB support Map objects?MongoDB 是否支持 Map 对象?
【发布时间】:2016-07-07 06:39:22
【问题描述】:

假设我在 node.js 应用程序中有一个有序项目的地图:

var myMap = new Map();
myMap.set("a", "b");
myMap.set("c", "d");
myMap.set("e", "f");

然后我使用 MongoDB node.js 驱动程序将此地图存储在数据库中:

collection.insertOne({myMap: myMap});

存储的地图如下所示:

{ "myMap" : { "a" : "b", "c" : "d", "e" : "f" } }

我知道 Map 的顺序是有保证的,但它是否保证按该顺序存储在 MongoDB 中?并且保证按这个顺序从MongoDB中读取?

这是一个非常简单的问题,但我在 MongoDB 文档中找不到任何关于它支持地图的信息。

【问题讨论】:

    标签: javascript node.js mongodb dictionary


    【解决方案1】:

    首先澄清一下。尽管 JavaScript 规范没有说对象“必须”保留键的顺序,但几乎每个实现实际上都保留了标准对象的键顺序。

    至于 MongoDB 文档,从技术上讲,它并没有记录在那里,因为实际的顺序保留因此是 BSON 规范,其中键的顺序 得到保证。而且 BSON 实际上并不局限于 MongoDB。

    至于实际问题,让我们看一下来自BSON serializer使用的内部函数的代码:

      } else if(object instanceof Map) {    //<-- Actually looks for the type and handles it
        var iterator = object.entries();
        var done = false;
    
        while(!done) {
    

    在列表中以此类推,基本上是迭代Map 中的每个条目,然后让每个成员接受相同的测试条件和分支(不完全是最干燥的代码),就像在一般顶级检查中所做的那样.

    然而,对此有一个“重要”说明,即 MongoDB 作为存储引擎可能需要在文档大小超出其初始分配的情况下重新定位磁盘上的数据。在这样的文档重写下,由于实际存储在 MongoDB 中的项目实际上不再是 Map,因此“可能”存储文档中的键“可能”被重新排序。

    多年来,出现了一些与内容重新排序相关的问题,尽管大多数问题已得到解决,但至少意识到这有可能发生并不是不合理的。

    从中吸取的重要教训应该是:

    1. 对象键通常会按照您创建它们的顺序进行序列化,尽管这并不是引擎“必须”这样做的硬性规范。

    2. 序列化为 BSON 的底层方法是区别对待 Map,并竭尽全力确保顺序得到维护。

    3. 由于最终的“存储”取决于服务器上的 BSON 规范,那么您真正“确保”订购商品的唯一方式是使用“数组”。当订单很重要时,这确实是您应该始终使用的。

    无论如何,Map 并不是真正为“有序键”实现的,我认为main documentation 完美地突出了“三巨头”:

    • 一个对象有一个原型,所以映射中有默认键。从 ES5 开始,这可以通过使用 map = Object.create(null) 绕过,但很少这样做。
    • Object 的键是字符串和符号,它们可以是 Map 的任何值。
    • 您可以轻松获取地图的大小,而您必须手动跟踪对象的大小。

    那是它们真的变得有用了。

    作为总结行“MongoDB 是否支持 Map 对象”?技术上没有,因为 BSON 没有对应的类型。但是驱动程序会正确地将其转换为 BSON 文档存储,当然一切都受制于那里应用的相同规则。因此,驱动程序和语言支持是“可选的”,因为 BSON 中没有任何内容可以说明这是 Map,那么由实现的代码将数据读入类似的“哈希/映射”存储中相同的规则。

    如果您因此只是“真正”对始终保持插入/维护顺序感兴趣,那么请改用“数组”。

    【讨论】:

    • “虽然 JavaScript 规范没有说对象“必须”保留键的顺序”——它有点像 ecma-international.org/ecma-262/6.0/…
    • @zerkms 无论如何都不是这里的重点。这就是人们“理解”规范的方式,因此MapObject 之间的区别。有点模棱两可,但这里真正的关键在于 BSON 处理。我确实注意到Map 文档故意不做这样的区分。
    • 我同意你的回答(目前唯一的赞成票是我的),我的观点是,从技术上讲,说规范没有任何东西在技术上是不正确的。
    • @zerkms 我不是在争论。但我很现实的是,9/10 的人(或者至少是那些找到这个主题的人)可能已经查看或将查看 Does JavaScript Guarantee Object Property Order 并且大多数人可能会跳出来得出结论 “那我会使用 Map! "。因此,虽然最近的文献可能在解释上有所不同,但历史信息就在那里。此外,我们正在告诉人们“无论如何都已订购”,以及当“订购”至关重要时要做的最终事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 2020-09-14
    • 1970-01-01
    • 2013-07-09
    相关资源
    最近更新 更多