What is the mongo compound index keyword arrangement rule? Numbers first, strings later?

When I used numbers as keys, the compound index prefixes created were not as expected。

To define a compound index:

admin> use TestDB
TestDB> db.createCollection('coll')
TestDB> db.coll.createIndex({4:1,1:-1},{unique:true})
TestDB> db.coll.getIndexex()

Output

[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  { v: 2, key: { '1': -1, '4': 1 }, name: '1_-1_4_1', unique: true }
]

I expected 4 to be the prefix of the index, but it turned out to be 1, why? It looks like the sorting happens

And when I use strings as keywords, the results are completely inconsistent。

Following:

TestDB> db.createCollection("coll2")
TestDB> db.coll2.createIndex({'s':1, 'a':-1},{unique:true})

Output

[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  { v: 2, key: { s: 1, a: -1 }, name: 's_1_a_-1', unique: true }
]

What? It doesn’t seem to be sorting.

Welcome to the MongoDB Community @limian_huang!

The problem you are observing is a side effect of how JavaScript treats objects with numeric keys (or keys that look like numbers). JavaScript interpreters will sort numeric key names ahead of alphanumeric key names, which leads to unexpected outcomes where order is important (for example, MongoDB index definitions). This behaviour is part of the JavaScript specification: ECMAScript 2015 Language Specification – ECMA-262 6th Edition.

My strong recommendation would be to use alphanumeric keys and avoid numeric keys (or strings that look like numbers). You can also use an order-preserving data structure like a Map in JavaScript, but this will still be an easy path to bugs.

Earlier discussion: Sorting multiple fields produces wrong order - #3 by Stennie.

Regards,
Stennie

4 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.