如何在mongoose模式中添加子文档

我正在尝试在node.js / Express的mongoose模式中创build一个子文档。

我有两个模式:成员和地址

Member.js

// app/models/member.js // load mongoose since we need it to define a model var mongoose = require('mongoose'), Schema = mongoose.Schema var Address = require('./address'); var MemberSchema = Schema({ FName : String, LName : String, address : [Address], phone : { type : String, number : String }, email: String, gender: String, DOB: Date, rank : { level : String, updated: { type: Date, default: Date.now } }, Awards : { personal : Boolean, award : { type : Schema.Types.ObjectId, ref : 'Award' }, granted: { type: Date, default: Date.now } } }); module.exports = mongoose.model('Member', MemberSchema); 

Address.js

 // app/models/address.js // load mongoose since we need it to define a model var mongoose = require('mongoose'), Schema = mongoose.Schema var AddressSchema = Schema({ type : String, street1 : String, street2 : String, City : String, State : String, Zip : Number, Lat : Number, Lng : Number }); module.exports = mongoose.model('Address', AddressSchema); 

我的意图是创build一个成员,然后添加一个地址。 成员的POST调用工作。 但是,在执行POST调用地址时,它会失败,说未定义,我找不到错误的位置。 我希望找出如何更好地将地址添加到我的成员模式。

routes.js

  app.route('/api/member') .get(function(req, res) { ... .post(function(req, res) { var new_member = new member(); new_member.FName = req.body.fname; new_member.LName = req.body.lname; new_member.DOB = req.body.DOB; new_member.email = req.body.email; new_member.gender = req.body.gender; new_member.save(function(err) { if (err) res.send(err); res.json({ message: 'Member Created!' }); }); }); app.route('/api/member/:member_id/address') .post(function(req, res) { member.findById(req.params.member_id, function(err, member) { if (err) return (err); new_address = new address(); new_address.type = req.body.atype; new_address.street1 = req.body.street1; new_address.street2 = req.body.street2; new_address.City = req.body.City; new_address.State = req.body.State; new_address.Zip = req.body.Zip; new_address.Lat = req.body.Lat; new_address.Lng = req.body.Lng; console.log(new_address); member.address.push(new_address); res.json({ message : "Address added!!" }); }); }); 

就像我说的那样,join会员很简单。 添加地址会导致以下错误:

 /Users/arcee123/projects/MCARS/node_modules/mongoose/lib/utils.js:419 throw err; ^ TypeError: undefined is not a function at Array.MongooseArray._cast (/Users/arcee123/projects/MCARS/node_modules/mongoose/lib/types/array.js:108:30) at Object.map (native) at Array.MongooseArray.push (/Users/arcee123/projects/MCARS/node_modules/mongoose/lib/types/array.js:262:23) at Promise.<anonymous> (/Users/arcee123/projects/MCARS/app/routes.js:108:24) at Promise.<anonymous> (/Users/arcee123/projects/MCARS/node_modules/mongoose/node_modules/mpromise/lib/promise.js:162:8) at Promise.emit (events.js:107:17) at Promise.emit (/Users/arcee123/projects/MCARS/node_modules/mongoose/node_modules/mpromise/lib/promise.js:79:38) at Promise.fulfill (/Users/arcee123/projects/MCARS/node_modules/mongoose/node_modules/mpromise/lib/promise.js:92:20) at /Users/arcee123/projects/MCARS/node_modules/mongoose/lib/query.js:1833:13 at model.Document.init (/Users/arcee123/projects/MCARS/node_modules/mongoose/lib/document.js:251:11) 15 Jun 15:45:49 - [nodemon] app crashed - waiting for file changes before starting... 

我哪里错了? 谢谢

更新1:地址推送的.post调用现在看起来像这样:

 .post(function(req, res) { member.findById(req.params.member_id, function(err, member) { if (err) return (err); new_address = new address(); new_address.type = req.body.atype; new_address.street1 = req.body.street1; new_address.street2 = req.body.street2; new_address.City = req.body.City; new_address.State = req.body.State; new_address.Zip = req.body.Zip; new_address.Lat = req.body.Lat; new_address.Lng = req.body.Lng; console.log(new_address); if(member.address === undefined){ member.address.push(new_address); } else{ member.address = [new_address]; } member.save(function(err) { if (err) res.send(err); res.json({ message: 'Address created!!!' }); }); }); }); 

由于从数据库检索模型时,Mongoose不需要地址字段,所以字段将不会被定义。 因此,您将无法添加地址字段。 你应该检查它是否存在

 if(member.address === undefined){ member.address.push(new_address); } else{ member.address = [new_address]; } 

编辑:你也将不得不把它保存回数据库。 (你也可以看看更新function)

就像@ Treesrule14所说,如果你没有初始member.address,你需要将它设置为[new_address]。 您将文档保存在第一个path中,而不是第二个path。 在第二条路线中,您只是返回文档而不保存它。

如果您始终想要一个地址字段(即使它是空的),您可以将成员模式中的地址字段更改为address: {type: [address], default:[]} 。 这将确保一个空数组默认情况下会被设置,并且您可以推送它或者读取它的长度,而不用担心它是未定义的。