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 сама справится с этим.