Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does MongoDB support Map objects?

Suppose I have a Map of ordered items in a node.js application:

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

I then store this map in a database using the MongoDB node.js driver:

collection.insertOne({myMap: myMap});

The stored map looks like:

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

I know that a Map's order is guaranteed, but is it guaranteed to be stored in MongoDB in that order? And is it guaranteed to be read from MongoDB in that order?

It's a pretty simple question, but I couldn't find anything in the MongoDB documentation about it supporting Maps.

like image 552
SilentByte Avatar asked Mar 20 '16 20:03

SilentByte


1 Answers

First a clarify. Though the JavaScript spec does not say that an object "must" retain the order of keys, just about every implementation actually keeps the key order on standard objects anyway.

As for MongoDB documentation, then technically it is not documented there because the actual retention of order is therefore a BSON spec where the order of keys is guaranteed. And BSON is not actually restricted to MongoDB.

As for the actual question, let's look at the code from the from the inner functions of the BSON serializer used:

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

    while(!done) {

And so on in the listing, which is basically iterating each entry in the Map and then subjects each member to the same test conditions and branching ( not exactly the most DRY code ) as would be done on general top level inspection.

Thre is however one "big" note on this, which is that MongoDB as a storage engine may need to re-locate data on disk in cases where the document size outgrows its initial allocation. Under such document re-writes, it "may" be possible that since the items actually stored in MongoDB are no longer actually a Map, that the keys in the stored document "may" become re-ordered.

There have been several issues raised over the years related to content re-ordering, and though most have been fixed, it would not be un-reasonable to at least be aware that this has a possibility of happening.

The big lesson to take away from this should really be that:

  1. Object keys are generally going to be serialized in the order you created them anyway, despite it not being a hard specification that engines "must" to that.

  2. The underlying method of serializing to BSON is treating Map differently, and is going out of it's way to make sure the order is maintained.

  3. Since ultimate "storage" lies with the BSON spec on the server, then the only way you truly "assure" ordered items is with an "array". And that is really what you should always use when order is important.

Map's are not really implemented just for "ordered keys" anyway, and I think the main documentation highlights the "big three" perfectly:

  • An Object has a prototype, so there are default keys in the map. This could be bypassed by using map = Object.create(null) since ES5, but was seldomly done.
  • The keys of an Object are Strings and Symbols, where they can be any value for a Map.
  • You can get the size of a Map easily while you have to manually keep track of size for an Object.

That's were they really do become useful.

As a summary line "Does MongoDB support Map objects"? Tecnically No, since there is no corresponding type for BSON. But the driver will convert it correctly to store as a BSON document, but of course everything is subject to the same rule applied there. Driver and language support is therefore "optional", since there is nothing in the BSON to say this is a Map, then it would be up to the implemented code to read the data into similar "Hash/Map" storage that followed the same rules.

If you are therefore only "really" interested in always maintaining order of insertion/maintenance, then use an "array" instead.

like image 129
Blakes Seven Avatar answered Sep 18 '22 21:09

Blakes Seven