19

The MongoDB documentation states:

For indexes with more than one key (i.e. compound indexes) the sequence of fields is important.

But ECMAScript defines an object as follows:

An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function.

When using MongoDB in node.js (for example by using this module), you're using server side javascript, like the example below.

How do you specify a sequence when MongoDB expects an object (AKA unordered collection of properties)?

collection.ensureIndex({
    date    : -1,
    client  : 1,
    product : 1
});
Redsandro
  • 10,080
  • 11
  • 64
  • 94
  • I wouldn't worry about the "unordered" property of JavaScript because they implemented their own version of js for the shell. Try `show dbs` and you'll see what I mean. – Matt Kneiser Aug 29 '13 at 15:26
  • Sorry, I forgot to mention Node.js (javascript) as the scripting language. – Redsandro Aug 29 '13 at 15:42
  • 1
    The properties may not in practice necessarily be quite as unordered as the ECMA spec dictates that they *may* be ( http://jsfiddle.net/D4zC8/2/ ). In Chrome and IE 10, the key order is consistent there. It wouldn't surprise me too much if a new fresh object literal behaved that way in all the major implementations. It seems pretty crazy to release code relying on that behavior, though. In Chrome, if I delete a property and replace it, the key order changes. In IE10, it doesn't. – 15ee8f99-57ff-4f92-890c-b56153 Aug 29 '13 at 15:46

1 Answers1

11

In MongoDB, the order of fields in a document is indeed significant, and all language drivers provide a means of specifying documents that way, even if the underlying programming language does not have such a concept.

The document format that MongoDB uses in its shell is JSON-like but not strict JSON. Among other things, order of fields is always preserved.

In Javascript, the standard defines fields as unordered, so implementations are free to ignore/not preserve the ordering. But in practice, all implementations do preserve the ordering. In particular the V8 engine preserves the ordering, which is the engine used in node.js so it's no problem.

Redsandro
  • 10,080
  • 11
  • 64
  • 94
drmirror
  • 3,550
  • 24
  • 26
  • I forgot to mention that this is about using `MongoDB` in `Node.js` which is server side javascript. So my worries are not about how Mongo handles it internally, but the javascript part. – Redsandro Aug 29 '13 at 15:40
  • 3
    The V8 engine does indeed preserve ordering, although it is defined as unordered in the standard. That is a grey area that currently seems to be handled sufficiently well (because all environments essentially preserve ordering), but may need to be more closely looked at in the future. – drmirror Aug 29 '13 at 15:47
  • Some testing shows that V8 indeed preserves this order all the time. You should edit your comment into your answer and I will accept it. – Redsandro Aug 29 '13 at 19:55
  • I've edited your answer in order to emphasis the actual answer (pending review), and accepted it. – Redsandro Oct 14 '13 at 19:35
  • 1
    Given the spec this seems like a dangerous assumption to make for such a widely-used piece of software. Does the API allow you to use an array instead of an object, just to make sure it's safe in the future? – download May 05 '14 at 18:19
  • 1
    @download According to [this V8 bug report](https://code.google.com/p/v8/issues/detail?id=164), the order is maintained for non-numeric names. The node.js driver also allows a syntax of `coll.ensureIndex([[a: 1], [b: -1]], cb)` if you don't want to rely on that. – JohnnyHK Feb 17 '15 at 04:10