NodeJS 和 Mongoose:将元素添加到现有的空数组
Posted
技术标签:
【中文标题】NodeJS 和 Mongoose:将元素添加到现有的空数组【英文标题】:NodeJS & Mongoose: Add element to existing empty array 【发布时间】:2016-02-19 00:53:33 【问题描述】:我正在构建一个 NodeJS 应用程序,用于根据 MSQL 数据库中的数据创建报告。所有与应用程序相关的数据都使用 Mongoose 存储在 MongoDB 中。我的猫鼬模型包含一个空数组,然后由用户通过 Rest-API 填充。
向数组添加新元素时出现错误。我已经用model.array.push(object); model.save()
和findByIdAndUpdate(...)
试过了。找到我的代码,包括以下两种不同的尝试:
Mongoose 架构
var sqlSchema = mongoose.Schema( // Schema to store information about SQL-procedures
'name': String,
'inputs': [
'name': String,
'type': String,
'value': String,
'adjustable': Boolean
]
);
REST API
我的应用程序通过 POST 接受“输入”数组的新元素:
var mongoose = require('mongoose'),
SqlProcedure = mongoose.model('SqlProcedure');
// ...
router.post('/sql/:id/inputs', function(req, res)
SqlProcedure.findById(req.params.id, function(err, sql)
if(err)
res.send(msg.error('error retrieving sql-procedure', err));
else
if(sql.inputs.length > 0) // catch empty array
for(var key in sql.inputs)
if(sql.inputs[key].name == req.body.name)
return res.send(msg.error('input already in inputs', err));
var data = req.body;
var input =
name: data.name,
type: data.type,
value: data.value,
adjustable: data.adjustable
;
// attempt one or two
);
);
尝试一:
sql.inputs.push(input); // EXCEPTION 1
sql.save(function(err)
// fancy errorhandling
return res.send(msg.ok(sql));
);
尝试二:
SqlProcedure.findByIdAndUpdate(req.params.id,
$push: inputs: input, // EXCEPTION 2
safe: true, upsert: true,
function(err, sql)
// fancy errorhandling
res.send(msg.ok('input added to sql-procedure' + req.params.id));
);
例外情况
尝试一:
throw new CastError('string', value, this.path);
^
Error
at MongooseError.CastError (\node_modules\mongoose\lib\error\cast.js:18:16)
at SchemaString.cast (\node_modules\mongoose\lib\schema\string.js:434:9)
at Array.MongooseArray.mixin._cast (\node_modules\mongoose\lib\types\array.js:124:32)
at Array.MongooseArray.mixin._mapCast (\node_modules\mongoose\lib\types\array.js:295:17)
at Object.map (native)
at Array.MongooseArray.mixin.push (\node_modules\mongoose\lib\types\array.js:308:25)
at Query.<anonymous> (\app\api\sql_procedure.js:69:28)
at \node_modules\mongoose\node_modules\kareem\index.js:177:19
at \node_modules\mongoose\node_modules\kareem\index.js:109:16
at doNTCallback0 (node.js:417:9)
at process._tickCallback (node.js:346:13)
尝试二:
"stack": "Error
at MongooseError.CastError (\\node_modules\\mongoose\\lib\\error\\cast.js:18:16)
at SchemaArray.cast (\\node_modules\\mongoose\\lib\\schema\\array.js:156:15)
at SchemaArray.cast (\\node_modules\\mongoose\\lib\\schema\\array.js:167:17)
at Query._castUpdateVal (\\node_modules\\mongoose\\lib\\query.js:2384:22)
at Query._walkUpdatePath (\\node_modules\\mongoose\\lib\\query.js:2298:27)
at Query._castUpdate (\\node_modules\\mongoose\\lib\\query.js:2227:23)
at castDoc (\\node_modules\\mongoose\\lib\\query.js:2430:18)
at Query._findAndModify (\\node_modules\\mongoose\\lib\\query.js:1752:17)
at Query._findOneAndUpdate (\\node_modules\\mongoose\\lib\\query.js:1620:8)
at \\ITZReport\\node_modules\\mongoose\\node_modules\\kareem\\index.js:156:8
at \\node_modules\\mongoose\\node_modules\\kareem\\index.js:18:7
at doNTCallback0 (node.js:417:9)\n at process._tickCallback (node.js:346:13)",
"message": "Cast to undefined failed for value \"[object Object]\" at path \"inputs\"",
"name": "CastError",
"value": [
"adjustable": "true",
"value": "Harry Potter",
"type": "String",
"name": "salesman"
],
"path": "inputs"
要插入的数据
name: 'salesman',
type: 'String',
value: 'Harry Potter',
adjustable: 'true'
我是 NodeJS 和 mongoose 的新手,我花了好几个小时试图自己解决这个问题。如果有人可以帮助我,那就太好了!
提前致谢, dj2bee
更新
我想我应该澄清一下用户与 REST-API 交互的过程:
-
用户通过传递
name
。此时,name
已设置,inputs
-array
是空的。
在下一步中,用户将新记录添加到
inputs
-array 一个一个。 name
保持原样且仅
新的 inputs
被添加到数组中。
用户应该能够编辑或删除条目
inputs
-array.
将adjustable
的数据类型更改为String 并没有进行任何更改。我还尝试了硬编码属性而不是通过 HTTP-POST 传递它们 - 仍然是同样的异常。
【问题讨论】:
【参考方案1】:经过数小时的网络搜索并测试我的代码中最奇怪的东西后,我找到了解决方案: 您不能在 mongoose-schema 中将字段命名为“类型”。就是这样。
正确的代码如下所示:
Mongoose 架构
var sqlSchema = mongoose.Schema(
'name': String,
'inputs':
'name': String,
'datatype': String, // you can't name this field 'type'
'value': String,
'adjustable': Boolean
);
REST API
router.post('/sql/:id/inputs', function(req, res)
SqlProcedure.findById(req.params.id, function(err, sql)
if(err)
res.send(msg.error('error retrieving sql-procedure', err));
else
if(!sql)
return res.send(msg.error('no sql-procedure found with id '
+ req.params.id, null));
// check for duplicates
var data = req.body;
var input =
'name': data.name,
'datatype': data.type,
'value': data.value,
'adjustable': data.adjustable
;
SqlProcedure.findByIdAndUpdate(req.params.id,
$push: inputs: input,
safe: true, upsert: true,
function(err, sql)
// fancy error handling
);
);
);
【讨论】:
【参考方案2】:您应该将您的数据插入为
name: 'salesman',
inputs: [name: 'salesman',
type: 'String',
value: 'Harry Potter',
adjustable: true]
即true 不带引号和输入作为数组
否则在模式中可调整为字符串,并在模型定义中将输入作为数组删除
var sqlSchema = mongoose.Schema( // Schema to store information about SQL-procedures
'name': String,
'type': String,
'value': String,
'adjustable': String
);
【讨论】:
我将 'adjustable' 硬编码为 true 但仍然得到相同的错误:Cast to undefined failed for value \"[object Object]\" at path \"inputs\" 我错过了模型将所有输入作为数组。请查看更正后的数据name
是在向数组添加记录之前设置的:请参阅上面的更新。我不知道我还能尝试什么来解决这个问题。这有点令人沮丧:D以上是关于NodeJS 和 Mongoose:将元素添加到现有的空数组的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 mongoose 和 NodeJs 在 Mongodb 的数组字段中插入数据
如何在 lambda 中使用 node-js 将我的文件添加到现有的 zip 文件夹?
如何在 Mongoose NodeJS 中使用聚合从数组中检索特定元素
NodeJS + Mongoose:MissingSchemaError:模式尚未注册模型“类别”