javascript - 从查询转换为数字失败。Node.js Express 猫鼬
问题描述
我刚开始使用 Node Express MongoDb 和 API 设计,我正在尝试为产品建立一个评级系统。
我添加了三个字段:
totalRating: { type: Number, required: false },
ratings: { type: Number, required: false },
averageRating: {
type: Number, required: false, default: function () {
return this.totalRating / this.ratings
}
},
Put
端点可以接收带有修改后的body
对象(CRUD 的 Ùpdate),或者接收rating
将用于增加 totalRating 参数的参数,该参数除以评级将计算要显示的平均评级。如果我直接传递一个数字值($inc: { totalRating: 5 } it works as expected The problem is that getting the
rating 查询参数到一个数字会失败,所以该方法会抛出一个错误:
rating is: { rating: '4' }
Mongoose updateProductById rating error: CastError: Cast to Number failed for value "NaN" (type number) at path "totalRating"
at model.Query.exec (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/query.js:4470:21)
at model.Query.Query.findOneAndUpdate (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/query.js:3122:8)
at Function.Model.findOneAndUpdate (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/model.js:2520:13)
at Function.Model.findByIdAndUpdate (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/model.js:2647:32)
at exports.updateProductById (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/api/src/controllers/product.controller.js:399:13)
at handleReturn (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:24:23)
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:64:7
at handleReturn (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:24:23)
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:64:7
at Layer.handle [as handle_request] (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express/lib/router/layer.js:95:5)
at next (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express/lib/router/route.js:137:13)
at exports.clientApiKeyValidation (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/api/src/auth_utils.js:15:9)
at handleReturn (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:24:23)
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:64:7
at handleReturn (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:24:23)
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:64:7 {
messageFormat: undefined,
stringValue: '"NaN"',
kind: 'Number',
value: NaN,
path: 'totalRating',
reason: AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
assert.ok(!isNaN(val))
at castNumber (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/cast/number.js:28:10)
at SchemaNumber.cast (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/schema/number.js:371:12)
at SchemaNumber.SchemaType.applySetters (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/schematype.js:1106:12)
at SchemaNumber.SchemaType._castForQuery (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/schematype.js:1584:15)
at SchemaNumber.castForQuery (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/schema/number.js:425:14)
at SchemaNumber.SchemaType.castForQueryWrapper (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/schematype.js:1551:20)
at castUpdateVal (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/helpers/query/castUpdate.js:518:21)
at walkUpdatePath (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/helpers/query/castUpdate.js:365:24)
at castUpdate (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/helpers/query/castUpdate.js:95:7)
at model.Query._castUpdate (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/query.js:4693:10)
at castDoc (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/query.js:4723:18)
at model.Query.Query._findAndModify (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/query.js:3602:22)
at model.Query.<anonymous> (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/query.js:3139:8)
at model.Query._wrappedThunk [as _findOneAndUpdate] (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/helpers/query/wrapThunk.js:16:8)
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/kareem/index.js:279:20
at _next (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/kareem/index.js:103:16) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '=='
},
valueType: 'number'
}
这是猫鼬模式:
const productSchema = new mongoose.Schema({
createdOnDate: {type: Number, required: true},
name: {type: String, required: true},
brand: {type: String, required: true},
price: {type: Number, required: true},
description: {type: String, required: true},
category: {type: String, required: true},
city: {type: String, required: true},
region: {type: String, required: true},
country: {type: String, required: true},
vendor: {type: String, required: true},
barcode: {type: String, required: true},
imageUrl: {type: String, required: true},
fullImages: {type: Array, required: true},
thumbNails: {type: Array, required: true},
// productImage: Uint8Array,
minimumStock: {type: Number, required: true},
availableQuantity: {type: Number, required: true},
soldQuantity: {type: Number, required: true},
totalRating:{type: Number, required: false},
ratings:{type: Number, required: false},
averageRating:{type: Number, required: false, default: function() {
return this.totalRating / this.ratings
}},
},
{ timestamps: true },);
这是更新方法:
exports.updateProductById = async (req, res) => {
const id = req.params.id;
const rating = req.query;
const updatedProduct = req.body;
if (rating) {
console.log('rating is: ', rating);
const value = parseInt(rating);
Product.findByIdAndUpdate(id,
{
$inc: { ratings: 1 },
$inc: { totalRating: value }
// $inc: { totalRating: 5 } works perfectly
},
{ new: true }, function (err, result) {
if (err) {
console.log('Mongoose updateProductById rating error: ', err);
res.status(500).send({
error: 'Internal error.'
});
return;
}
if (result != null) {
console.log('Mongoose updateProductById rating: ', result);
res.status(200).send({
message: 'Product rating updated successfully!',
data: result
});
}
else {
console.log('Mongoose updateProductById rating: No product found.');
res.status(404).send({
error: 'Product not found.'
});
}
});
} else {
Product.findByIdAndUpdate(id, updatedProduct, { new: true }, function (err, result) {
if (err) {
console.log('Mongoose updateProductById error: ', err);
res.status(500).send({
error: 'Internal error.'
});
}
if (result != null) {
console.log('Mongoose updateProductById: ', result);
res.status(200).send({
message: 'Product updated successfully!',
data: result
});
}
else {
console.log('Mongoose updateProductById: No product found.');
res.status(404).send({
error: 'Product not found.'
});
}
});
}
}
解决方案
如果您注意到当日志记录rating
等于{rating: "4"}
您req.query
想要的值时,请req.query.rating
尝试类似
const rating = req.query.rating
或者
const { rating } = req.query
推荐阅读
- python - 如何使用鼠标使图像文本出现并重新出现?
- angular - Angular 9:注入延迟加载服务时的拦截器循环依赖
- django - django url 模式的 url 参数未正确传递
- json - Pandas 读取 json 错误:OverflowError: Python int too large to convert to C long
- objective-c - 如何(不安全地)在 Swift 中按名称调用 dylib 函数?(直接翻译objective-c代码但遇到一般保护错误。)
- tcp - 使用 CSV 数据配置通过 JMeter 测试多个 API 的 TCP 调用时获取响应为空
- acumatica - 如何删除库存项目附加文件
- java - 在运行时更改 Hibernate 配置时遇到问题
- c# - 在带有 Aerial3D 视图的 UWP MapControl 中使用 json 样式表
- c - 如何在 Load Runner 中将特定日期转换为其他日期格式?