#node.js #mongodb
#node.js #mongodb
Вопрос:
Я очень новичок в Nodejs, не уверен, что могу задать здесь такую простую вещь. Когда я создал сервер узла для подключения к mongodb, получил эту ошибку:
Ошибка приведения к номеру для значения «NaN» при «count» пути
Но ошибка исчезла через несколько минут, и сервер снова каким-то образом запускается, а также была вставлена схема подсчета.
Я не могу найти что-то, что заставило его запустить снова. Я просто предположил, что мой сервер узла не смог получить значение, потому что схема «count» исчезла.
Но не могли бы вы помочь мне думать лучше.
Вот ошибка, которая у меня была раньше.
- Во-первых, не было схемы «подсчета», когда я проверял сбор данных в mongodb.
> db.datas.find()
{ "_id" : ObjectId("5cb39eca6e5e3971fa934a2d"), "name" : "myData", "__v" : 0 }
- Во-вторых, консоль сервера узла показала мне ошибку ниже:
Data ERROR: save: { ValidationError: data validation failed: count: Cast to Number failed for value "NaN" at path "count"
at ValidationError.inspect (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/error/validation.js:59:24)
at formatValue (util.js:430:38)
at inspect (util.js:324:10)
at format (util.js:253:18)
at Console.log (console.js:130:21)
at /home/gkh/Desktop/Dev/myapp/app.js:46:30
at /home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/model.js:4675:16
at /home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/utils.js:255:11
at $__save.error (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/model.js:471:16)
at /home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:246:48
at next (/home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:167:27)
at next (/home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:169:9)
at Kareem.execPost (/home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:217:3)
at _handleWrapError (/home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:245:21)
at /home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:272:14
at _next (/home/gkh/Desktop/Dev/myapp/node_modules/kareem/index.js:94:14)
errors:
{ count:
{ CastError: Cast to Number failed for value "NaN" at path "count"
at new CastError (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/error/cast.js:29:11)
at model.$set (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/document.js:1073:7)
at model.set [as count] (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/helpers/document/compile.js:140:26)
at /home/gkh/Desktop/Dev/myapp/app.js:44:15
at /home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/model.js:4675:16
at /home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/query.js:4184:12
at process.nextTick (/home/gkh/Desktop/Dev/myapp/node_modules/mongoose/lib/query.js:2741:28)
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
message: 'Cast to Number failed for value "NaN" at path "count"',
name: 'CastError',
stringValue: '"NaN"',
kind: 'Number',
value: NaN,
path: 'count',
reason: [Object] } },
_message: 'data validation failed',
name: 'ValidationError' }
- Вот часть app.js файл:
mongoose.connect("mongodb://localhost:27017/user-node");
var mongod = mongoose.connection;
mongod.once("open", function(){
console.log("DB connected!");
});
mongod.on("err", function(err){
console.log("DB err: ", err);
});
var dataSchema = mongoose.Schema({
name:String,
count:Number
});
var Data = mongoose.model('data', dataSchema);
Data.findOne({name:"myData"}, function(err, data){
if(err) return console.log("Data ERROR: ", err);
if(!data){
Data.create({name:"myData",count:0}, function(err, data){
if(err) return console.log("Data ERROR", err);
console.log("Counter initialized: ", data);
});
}
});
app.set("view engine", 'ejs');
app.use(express.static(path.join(__dirname '/public')));
// callback function list
// render to firstPage.ejs page with params or non-params
app.get('/', function(req, res){
Data.findOne({name:"myData"}, function(err, data){
if(err) return console.log("Data ERROR : /path: ", err);
data.count ;
data.save(function(err){
if(err) return console.log("Data ERROR: save: ", err);
res.render('firstPage', data);
});
});
});
// set count to 0
app.get('/reset', function(req, res){
setCounter(res, 0);
});
// check arg in req.query.count
app.get('/set/count', function(req, res){
if(req.query.count) setCounter(res, req.query.count);
else getCounter(res);
});
// placeholder : num
// any arg can place in num param
app.get('/set/:num', function(req, res){
if(req.params.num) setCounter(res, req.params.num);
else getCounter(res);
});
function setCounter(res, num){
console.log("...setCounter...");
Data.findOne({name:"myData"}, function(err, data){
if(err) return console.log("Data ERROR: ", err);
data.count=num;
data.save(function(err){
if(err) return console.log("Data ERROR: ", err);
res.render('firstPage', data);
});
});
}
function getCounter(res){
console.log("...getCounter...");
Data.findOne({name:"myData"}, function(err, data){
if(err) return console.log("Data ERROR", err);
res.render('firstPage', data);
});
}
Если я ошибаюсь или мой код неверен, пожалуйста, посоветуйте мне.
Заранее благодарю вас!
Комментарии:
1. Это возможно, если значение
count
равноNaN
при сохраненииMyData
. Можете ли вы показать нам, какую конечную точку вы вызываете? или какsetCounter()
вызывается?2. @Sridhar Ошибка возвращается при вызове [ localhost:3000/] .
setCounter()
Функция вызывается только в/reset
,/set/count
,/set/:num
.
Ответ №1:
Перед выполнением любой операции установите значение по умолчанию 0 в поле. Эта ошибка возникает из-за того, что полям не присвоено начальное значение.
Комментарии:
1. Спасибо @kaushik_pm, сегодня ты спас мой день
Ответ №2:
Ошибка приведения к номеру для значения «NaN» при «count» пути
Это возможно, если документ в БД не имеет атрибута count.
const Data = mongoose.model('data', dataSchema);
Data.findOne({ name: "myData" }, function (err, data) {
if (err)
return console.log("Data ERROR: ", err);
if (!data) {
Data.create({ name: "myData", count: 0 }, function (err, data) { //correct
if (err)
console.log("Counter initialized: ", data);
return console.log("Data ERROR", err);
});
}
});
Хотя вы правильно создали для новых записей, я подозреваю, что он может отсутствовать для нескольких устаревших записей и может иметь следующую структуру
db.datas.find()
{ «_id»: ObjectId(«5cb39eca6e5e3971fa934a2d»), «name»: «myData», «__v»: 0 }
Итак, когда вы выполняете вызов localhost:3000/
, документ count
будет undefined
, следовательно, когда вы data.count
и сохраните, он выдает ошибку.
Вам необходимо проверить undefined
, а затем обновить его.
app.get('/', function (req, res) {
Data.findOne({ name: "myData" }, function (err, data) {
if (err) {
return console.log("Data ERROR : /path: ", err);
}
if (!data.count) {
// for legacy records which doesn’t have this attribute
data.count = 0;
}
data.count ;
data.save(function (err) {
if (err) {
return console.log("Data ERROR: save: ", err);
}
res.render('firstPage', data);
});
});
});
Кроме того, поскольку вы используете mongoose для проверки и обновления документа. Вы можете рассмотреть возможность использования findOneAndUpdate()
Находит соответствующий документ, обновляет его в соответствии с аргументом обновления, передавая любые параметры, и возвращает найденный документ (если таковой имеется) в обратный вызов. Запрос выполняется, если передается обратный вызов, иначе возвращается объект запроса.
function setCounter(res, num) {
return Data.findOneAndUpdate({
name: 'myData'
}, {
count: num
}, {
new: true,
upsert: false
// if you don't want to create a new document if the record doesnt exist
}).then(doc => {
res.render('firstPage', doc);
}).catch(err => {
return console.log("Data ERROR: ", err);
});
}
Комментарии:
1. итак, в основном, эта проблема возникла из-за того, что я не проверил значение «data.count».
2. Как насчет моей функции setCounter, была ли это неэффективная структура? Кроме того, спасибо за вашу помощь. Ваш код очень полезен и прост
3. @yafomars да, вам нужно сделать эту проверку. Ранее setCounter выполнял 2 вызова. 1, чтобы получить записи, и 2, чтобы сохранить их. Но mongodb предлагает findOneAndUpdate , если мы используем это, мы можем выполнить все за один вызов. 🙂