Mongoose保存子文档数组

我努力保存一个子文档数组。 只是不会保存:

前端发送一个Day对象,它有一个标题数组,每个标题可以有一个内容数组(这是一个mongoose模式)。

var DaySchema = mongoose.Schema({ date: Date, startTime: Date, endTime: Date, title: String, order: Number, description: String, cohort: { type: objId, ref: 'cohort' }, instructors: [{ type: objId, ref: 'instructor' }], headings: [{ title: String, subTitle: String, content: [{ type:objId, ref: 'content' }] }] }); var ContentSchema = mongoose.Schema({ title: String, description: String, contentUrl: String, dueDate: Date, dateAssigned: Date, downloadUrl: String }); 

这是我正在使用PUT和POST一天的代码及其关联的内容对象。 除了保存内容之外,一切都可以使用 当我查看mongo shell时,标题下面的每个内容字段如下所示:

 content: [] 

有什么想法吗?

 exports.putdaycontent = function (req, res) { var dayId = req.params.dayId; var headings = req.body.headings; var day = req.body; var updateDay = function () { Day.update({_id: dayId}, day, {new: true, upsert: true}, function (err, day) { if (err) error.databaseError(req, res, err); res.send(day); }); }; if (headings) { for (var x = 0; x < headings.length; x++) { var h = headings[x]; if (h.content) { for (var y = 0; y < h.content.length; y++) { var c = h.content[y]; //If existing content update it if (c._id && c._id.length > 0) { Content.update({_id: c._id}, c, {new: true,upsert: true}, function (err, content) { }); } else { var content = new Content(c); h.content[y] = content; } } } } day.headings = headings; updateDay(); } else { updateDay(); } }; exports.postdaycontent = function (req, res) { var headings = req.body.headings; var day = req.body; var cohortId = day.cohort._id; var postDay = function () { var d = new Day(day); console.log("CONTENT DAYS:",d); d.save(function(err, newDay) { if (err) error.databaseError(req, res, err); Cohort.findOneAndUpdate({_id: cohortId}, {$push: {days: newDay}}, {upsert: true}, function(err, newCohort) { res.send({msg:"Successfully saved day to cohort"}); }); }); }; if (headings) { for (var x = 0; x < headings.length; x++) { var h = headings[x]; if (h.content) { for (var y = 0; y < h.content.length; y++) { var c = h.content[y]; var content = new Content(c); h.content[y] = content; console.log("CONTENT:",content); } } } day.headings = headings; } postDay(); }; 

这是我几天前在2015年6月22日面临的事情。这里是我在github上提出的问题的链接https://github.com/Automattic/mongoose/issues/3093


现在有两个解决你的问题。

  1. 每当你修改一个数组索引时,明确使用.set()

例如:

 doc.someArray.set('3', 'changed'); doc.save(); 

这里名为someArray的数组正在被改变,因此我们需要使用array.set方法来改变它。

缺点 :数组中的每个元素需要使用array.set()来设置,例如数组中的5个元素需要使用array.set来设置。


2.将数组标记为已修改,然后保存。

例如:

 doc.array[3] = 'changed'; doc.markModified('array'); 

这是另一种方式,当你不能显式调用array.set方法。 例如:在我的情况下,我用loadash合并文件并保存它,没有办法我可以使用array.set ,因此我使用array.markModified

Benifit:你不需要像在上面的array.set方法那样设置数组中的每个元素。

退税:

在每个数组的情况下,您将需要在保存之前将其标记为已修改。 例如:如果您的文档中有10个数组,则需要在保存之前将它们全部标记为已修改:例如,

  doc.markModified('array1'); doc.markModified('array2'); doc.markModified('array3'); 

mongoose仍然没有select将多个arrays标记为已修改。 我已经在上面分享的链接中请求了此function。

所以这会是这样的:

 profile.markAllModified(['arrayFirst','arraySecond','arrayThird','arrayFourth']); 

已被添加到里程碑mongoose4.0.7,希望我们很快看到这个function。

所以我假设mongoose只要有_id字段就可以保存子文件 – 但显然不是。 保存子文档数组的解决scheme是

  1. 从json为数组中的每个子文档创build一个新的Model对象
  2. 在每个对象上调用save()
  3. 父对象不关心子文档的_id是否存在 – 它甚至可以在将子文档本身保存到数据库之前存储它。

再次修复只是在子文档上调用.save()。

var content = new Content(c); content.save(); h.content[y] = content;

exports.putdaycontent = function(req,res){

 var dayId = req.params.dayId; var headings = req.body.headings; var day = req.body; var updateDay = function () { Day.update({ _id: dayId }, day, { new: true, upsert: true }, function (err, day) { if (err) error.databaseError(req, res, err); res.send(day); }); }; if (headings) { for (var x = 0; x < headings.length; x++) { var h = headings[x]; if (h.content) { for (var y = 0; y < h.content.length; y++) { var c = h.content[y]; //If existing content update it if (c._id && c._id.length > 0) { Content.update({ _id: c._id }, c, { new: true, upsert: true }, function (err, content) { }); } else { var content = new Content(c); content.save(); h.content[y] = content; } } } } day.headings = headings; updateDay(); } else { updateDay(); } };