Как стать автором
Обновить

MongoDB Native и ensureIndex

Решил написать небольшую заметку про ensureIndex при работе с MongoDB в NodeJS.

В работе ensureIndex в MongoDB native драйвер скрывается небольшой подвох, который с течением времени может проявиться.

Вся проблема кроется при работе с Compound Indexes: docs.mongodb.org/manual/core/index-compound/#prefixes

Дело в том, что при передаче объекта ключей { a: 1, b: 1, c: 1 }, создаются индексы: a, a + b, a + b + c, о чем и говорит документация, при этом порядок ключей играет роль при построении индекса.

Как известно, хэш не может гарантировать порядок следования ключей, как, например, отчетливо происходит в perl. В ecma 262 Object.keys говорится:

If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used in step 5 of this algorithm.


То есть порядок зависит от имплементации enumeration метода, а следовательно — при разной имплементации может быть разный порядок ключей в итоге, а следовательно — ваш ensureIndex может поломаться.

Обратимся к документации драйвера. Как видно, можно создать индекс двумя способами:

  1. передавая объект {firstname:1, lastname:1}
    collection.ensureIndex({firstname:1, lastname:1}, callback)
  2. или tuple: [[«firstname», 1], [«lastname», 1]]
    collection.ensureIndex([["firstname", 1], ["lastname", 1]], callback)


Проанализировав код драйвера, находим, что при передачи вызывается parseIndexOptions, который использует Object.keys.

Поэтому вывод напрашивается сам собой: второй способ вызова ensureIndex предпочтительнее, дабы избежать в будущем проблем.

Изучив драйвер для perl, видно:

In this example, we must use Tie::IxHash to preserve the ordering of the arguments to ensureIndex.


P.S. Обратите внимание на код в строках 250 и 261 — это копипаста?
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.