将项目添加到混合模式数组时,mongoose.save的结果不正确

以下是显示问题的function:

var mongoose = require('mongoose'); var connection = mongoose.createConnection('mongodb://localhost:27017'); connection.once('open', function () { var schema = new mongoose.Schema({ obj: [{}] //mongoose.Schema.Types.Mixed }); var Model = connection.model('mtest', schema); var model = new Model({ obj: [{ name: 'Original' }] }); model.save(function (err, res) { console.log('result 1', res); Model.findOne({_id: res._id}, function (err, res) { res.obj[0].name = 'Modified'; res.obj.push({ name: 'other' }); //res.markModified('obj'); // using markModified does not help res.save(function (err, res) { console.log('result 2', res); connection.close(); process.exit(); }); }); }) }); 

obj: obj: [ { name: 'Modified' }, { name: 'other' } ]的“result 2”的输出显示“ Modified ”。 但是,在数据库中,第一个项目的值仍然是“ Original ”。

只有在向数组中推入第二项时才会发生这种情况(否则第一项确实会被修改)。 添加markModified确实解决了这个问题。

我在模式中使用了一个空对象types的数组,因为实际上这个用例处理的是相互inheritance的模式,所以这里没有一个模式可以使用。

这是一个错误? 我发现唯一的解决方法是清除数组,然后再次添加所有项目。 我想知道是否有更好的解决scheme。

您可以改变您的markModified调用,以确定您在数组访问方法“外部”更改元素的索引:

 res.obj[0].name = 'Modified'; res.obj.push({ name: 'other' }); res.markModified('obj.0'); 

或切换到使用set数组访问方法提醒name (这看起来很愚蠢,但确实工作):

 res.obj[0].name = 'Modified'; res.obj.set(0, res.obj[0]); res.obj.push({ name: 'other' });