У меня есть схема Mongoose, которая использует числовое значение как _id
, например. 102375848308956134094
. Когда я сохраняю коллекцию и findById
в Mongoose или find({ _id: 102375848308956134094 });
в оболочке Mongo, верный документ возвращается, хотя _id
отличается от ранее предоставленного (вместо него 102375848308956140000
).Число, внесенное в обновление при сохранении в коллекции (MongoDB)
Это проблема, как если бы я, чтобы сохранить коллекцию в _id
102375848308956134095
(обратите внимание на последнюю цифру изменилось от 4
к 5
), MongoDB ошибки из (E11000 duplicate key error index... dup key: { : 1.023758483089561e+20
).
Is MongoDB рассматривает Number
как номер с плавающей запятой?
Ниже приведен пример запроса:
> db.users.find({ _id: 102375848308956134094 }).pretty();
{
"_id" : 102375848308956140000,
"access_token" : "",
"access_token_expires" : ISODate(""),
"given_name" : "Jonathon",
"refresh_token" : ""
}
Примечание: я удалил и т.д. значения access_token
.
Однако, когда этот документ был сохранен, я полностью указал значение _id
, которое должно быть 102375848308956134094
.
Любые идеи, что происходит?
Вот моя схема:
/*jslint es5: true, indent: 2, node:true, nomen: true, maxlen: 80, vars: true*/
'use strict';
module.exports = function (mongoose) {
var Schema = new mongoose.Schema({
_id: Number,
access_token: String,
access_token_expires: Date,
given_name: String,
refresh_token: String
});
return mongoose.model('User', Schema);
};
И это upsert
:
...
models.user.update(
{
_id: user.id
},
{
access_token: access_token,
access_token_expires: new Date(Date.now() + (59 * 60 * 1000)),
given_name: user.given_name,
refresh_token: refresh_token
},
{
upsert: true
},
/*TODO: Handle upsert errors*/
function (err, numberAffected, raw) {
if (err) {
console.log(err);
} else {
delete req.session.state;
req.session._id = user.id;
res.redirect('/');
}
}
);
...
Вся помощь, как всегда, очень ценится!
/Редактировать/
Я попытался @ ответ JohnnyHK в использовании Long
номера однако, _id
кажется, все еще хранится неправильно в документе. Он сохраняет _id
как -8304616133301175602
вместо 102375848308956134094
. Я пробовал несколько запросов к find
документам, но только с поставкой _id
, как -8304616133301175602
, возвращает правильный документ, например.
> db.users.find().pretty();
{
"_id" : NumberLong("-8304616133301175602"),
"access_token" : "ya29.1.AADtN_VyfAvBlam2HCERpI0JcJkcwg22t1124tZw0G7pgRyTcaIuGU-dX3H4Q-M",
"access_token_expires" : ISODate("2013-12-09T12:42:53.098Z"),
"given_name" : "Jonathon",
"refresh_token" : "1/-2GQ_s3JogCr45Z1CBKWBHTEcjE0Nda9xkpFFdl7wT0"
}
> db.users.find({ _id: 102375848308956134094 }).pretty();
> db.users.find({ _id: NumberLong(102375848308956134094) }).pretty();
> db.users.find({ _id: NumberLong('102375848308956134094') }).pretty();
Mon Dec 9 11:46:26.433 Error: could not convert "102375848308956134094" to NumberLong
> db.users.find({ _id: -8304616133301175602 }).pretty();
{
"_id" : NumberLong("-8304616133301175602"),
"access_token" : "",
"access_token_expires" : ISODate(""),
"given_name" : "Jonathon",
"refresh_token" : ""
}
Любые мысли относительно того, почему это может быть?
Я как бы думал, что-то подобное происходит. Благодаря! Будет ли это причиной каких-либо проблем для хранения _id как строки. Кроме того, очевидно, что ошибки не будут выбрасываться, если я попытаюсь вставить строку. Я не делаю никаких вычислений по номеру, поэтому я не вижу проблемы, кроме проблемы с производительностью? Я исхожу из фона MySQL, в котором могут влиять разные типы данных, потребляющих различное пространство и производительность. Любые мысли по этому поводу? –
@JonathonOates Хранение его как строки будет работать нормально, но оно будет намного менее эффективным, так как это 2 байта на символ; так что 42 байта вместо 8 для 64-битного целого. Вы все равно можете передавать значения Long в виде строк, и Mongoose будет конвертировать для вас, когда вы фактически взаимодействуете с БД, поэтому я бы пошел с Long. – JohnnyHK
'Long' 'появляется', который будет неправильно храниться в коллекции, и я не могу' find' запись, если я не запрошу точный (неправильный) номер, сохраненный как '_id'. Я отредактирую свой вопрос с примера :-) –