MongoDB и большие числовые идентификаторы документов

Mongodb использует формат BSON для хранения данных на диске. BSON определяет различные типы данных, включая подписанные int64 для хранения больших целых чисел.

Попробуем сохранить документ с большим идентификатором (887190505588098573), который вписывается в диапазон со знаком int64 (его абсолютное значение меньше 2^63)

> db.query.insert({_id: 887190505588098573, 'q': 'zzz'})
> db.query.find({_id: 887190505588098573})
{ "_id" : 887190505588098600, "q" : "zzz" }

Ну, мы получили ответ с идентификатором документа, который отличается от идентификатора, который мы запросили.

Что мне не хватает?

2 ответа

Javascript не может обработать такое большое число - он обрабатывает только целые числа до 2 ^ 53.

Вы можете увидеть это, поставив 887190505588098573 в консоль JS, и вы получите 887190505588098600 назад.

Клиенты не-JS с этим справляются. Например, Ruby:

jruby-1.7.12 :013 > c["test"]["query"].insert({_id: 887190505588098574, q: 'zzz'})
 => 887190505588098574
jruby-1.7.12 :016 > c["test"]["query"].find({_id: 887190505588098574}).next()
 => {"_id"=>887190505588098574, "q"=>"zzz"}

Здесь NumberLong введите MongoDB, который соответствует 64-битному целому числу ( тип BSON 18)

db.collection.insert({ "_id": new NumberLong(887190505588098573) })

Так что совпадает на $type

db.collection.find({ "_id": { "$type": 18 } })

Хотя пробег может варьироваться в зависимости от того, где вы можете использовать это, поскольку клиент браузера может получить расширенную форму JSON этого, но есть ограничения на то, как его можно использовать без аналогичного переноса в класс для его обработки.

Работать с большинством других языков должно быть хорошо, так как драйвер приведёт к нативному типу. Так что это действительно зависит от вашей языковой реализации в отношении практичности этого. Но MongoDB сама справится с этим.

Другие вопросы по тегам