Mongoose调用save()保存数据时报Cast to [Boolean]类型转换错误
问题描述
我使用Angular作为前端框架,NodeJS作为后端框架。
我编写了一个路由接口,用于将前端传递的数据保存至数据库。当执行save()方法时,抛出如下错误:
err : ValidationError: conf.0: Cast to [Boolean] failed for value "[ {
name: 'v', percentage: 2, type: false, status: true } ]" (type string)
at path "conf.0"
相关实现代码
后端存储路由
app.post("/api/submitTaxCollection", (req, res) => { console.log(req.body); const submitTaxSchema = new addTaxesSchema(req.body); try { submitTaxSchema.save(function (err) { if (err) return console.log("err : " + err); }); } catch (error) { console.log("ERROR : " + error); return res.send(error); } });
Mongoose Schema定义
var mongoose = require("mongoose"); //Define a schema var taxSchema = mongoose.Schema; var AddTaxSchema = new taxSchema({ parentId: String, conf: [ { name: String, percentage: Number, type: Boolean, status: Boolean, }, ], }); var newTaxesSchema = mongoose.model("addTaxSchema", AddTaxSchema); module.exports = newTaxesSchema;
Angular端数据模型
export class TaxRatesConfigurationsModel { name: string = ""; percentage: number = 0; type: boolean = false; status: boolean = true; } export class TaxRatesModel { parentId: string = ""; conf: TaxRatesConfigurationsModel[] = []; }
前端接口调用逻辑
this._httpService .post(environment.url + "/api/submitTaxCollection", request) .subscribe((data) => { console.log(data); });
Node端打印的请求体
{ parentId: '23948923nur8cw9yicnyu', conf: [ { name: 'v', percentage: 2, type: false, status: true } ] }
问题原因
报错由两个问题共同导致:
- Mongoose保留关键字冲突:
type是Mongoose Schema的内置保留关键字,作用是声明字段的类型。你在conf数组的子结构中直接写type: Boolean时,Mongoose不会将其识别为「子文档内存在名为type、类型为Boolean的字段」,反而会把整个数组定义解析为「conf字段是布尔值构成的数组(即[Boolean])」,完全忽略name、percentage、status等其余字段定义。这和报错信息中提示的“尝试转换为[Boolean]类型失败”完全吻合。 - 请求体未被正确解析:报错信息中标注传入值类型为
string,说明实际传入Mongoose的conf字段是序列化后的JSON字符串,而非JS对象数组。控制台打印出的对象结构是console.log自动做的可视化解析,不代表实际值类型,根源是Express的请求体解析中间件配置错误。
修复方案
- 解决Schema关键字冲突,二选一即可:
- 给所有字段加上显式的类型声明包裹,明确告知Mongoose
type是业务字段名而非类型声明关键字:
var AddTaxSchema = new taxSchema({ parentId: { type: String }, conf: [ { name: { type: String }, percentage: { type: Number }, type: { type: Boolean }, status: { type: Boolean }, }, ], });- 单独定义子文档Schema,从根源消除解析歧义:
const ConfItemSchema = new taxSchema({ name: String, percentage: Number, type: Boolean, status: Boolean }) var AddTaxSchema = new taxSchema({ parentId: String, conf: [ConfItemSchema] }); - 给所有字段加上显式的类型声明包裹,明确告知Mongoose
- 修正请求体解析配置,确保以下两行中间件代码写在所有路由注册逻辑之前:
app.use(express.json()); app.use(express.urlencoded({ extended: true })); - 增加入参校验:实例化Model前先通过
typeof req.body.conf确认类型,如果是字符串,先执行JSON.parse(req.body.conf)转换为对象数组再传入。
内容的提问来源于stack exchange,提问作者Code
相关产品推荐
相关产品推荐

