Порядок следования частей на ObjectId в BSON
При попытке вручную запросить объекты в MongoDB, используя ObjectID, я обнаружил проблему в драйвере mongodb. Интерпретация частей BSON ObjectId представляется неверной. Я пытаюсь это исправить, но не могу найти достойную спецификацию, чтобы сделать это правильно.
В документации mongodb идентификатор объекта определен как 12 байт:
* a 4-byte value representing the seconds since the Unix epoch,
* a 3-byte machine identifier,
* a 2-byte process id, and
* a 3-byte counter, starting with a random value
В сети я нахожу упоминания о
"Note that the timestamp and counter fields must be stored big endian unlike the rest of BSON."
Но я не могу найти источник этого. Это имеет смысл, поскольку идентификаторы, которые я могу видеть в Монго, действительно являются меткой байтов для метки времени. Большинство идентификаторов объектов имеют в основном нулевые значения, поэтому их трудно понять. Моя проблема состоит в том, чтобы найти источник этого определения с прямым порядком байтов и, если это действительно так,
* time is big-endian
* machine id is little-endian
* process id is little-endian
* counter is big-endian
2 ответа
Да, это, по-видимому, правильно. Из исходного кода сервера mongodb по адресуsrc/mongo/bson/oid.h
:
Типичным содержимым BSON ObjectID является 12-байтовое значение, состоящее из 4-байтовой метки времени (секунды с начала эпохи), 3-байтового идентификатора компьютера, 2-байтового идентификатора процесса и 3-байтового счетчика. Обратите внимание, что поля timestamp и counter должны храниться с прямым порядком байтов в отличие от остальной части BSON. Это потому, что они сравниваются побайтово, и мы хотим обеспечить в основном увеличивающийся порядок.
(акцент мой).
Временная метка также содержит много кода с заменой байтов, поэтому кажется, что комментарий не устарел или что-то в этом роде, также имеет смысл порядок байтов.
Глядя на исходный код драйвера Go (который сотрудники MongoDB оценили как самый продвинутый и хорошо написанный драйвер), становится ясно, что все поля в ObjectID хранятся как big-endian:
http://bazaar.launchpad.net/+branch/mgo/v2/view/head:/bson/bson.go#L295
Цель этого, безусловно, состоит в том, чтобы иметь возможность сортировать идентификаторы объектов в лексикографическом порядке (побайтно) и иметь числовые значения в указанном порядке.
Идентификатор машины обрабатывается как непрозрачный 3-байтовый массив, поэтому он не обязательно в любом порядке.