大家好,不知为什么mongoose不能更新嵌入的数组中的数据。 ‘’’ var MySchema=new Schema({ id:ObjectId, msgbody:String, replymsg:[ReplyPerson] });
var ReplyPerson=new Schema({ rid:ObjectId, parentid:ObjectId, rmsg:String, rimgurls:[String], });
传调参数示例: params:{schemaid:1,childid:2};
就是MySchema中的replymsg数组中找rid为2的记录,并把其中的rmsg改为’cccccccc’
exports.myupdate = function (params, data, callback) { MySchema.findOne({_id:params.schemaid}, function (err, mySchema) { if (err) { console.log(‘Err:’ + err); return callback(err); } if (!mySchema) { return callback(new Error(‘无可更新内容!’)); } //如果直接这样赋值是可以改变的。 mySchema.replymsg=[‘aaaa’,’bbbb’]; for(var key in mySchema.replymsg){ // console.log('key:’+key); var obj=mySchema.replymsg[key]; // console.log('obj:’+obj); if(obj.parentid==params.schemaid && obj.rid=params.childid){ //通过调试,这是是会执行到的,但最终mongodb 中值还是原来的值。 mySchema.replymsg[key].rmsg=’cccccccccccccc’; break; } } mySchema.save(callback); }); }; ‘’’ 但当我执行这段代码后,mongodb中记录一直没改变。 可如果我不是通过改变数组中的记录内容,直接把整个数组赋值mySchema.replymsg=[‘aaaa’,’bbbb’];是会改变值的。 难道mongoose不能自动检测到数组中的值已经变化过,如果是这样,那么有没有什么值可以手动设置让mongoose知道这些值变化了呢? 非常感谢! 调了一个上午,始终不行,求救!!!
首先MySchema.findById(params.schemaid,function(err,reply){
如果reply有值, 那么reply.replymsg就是子文档的值 通过一个子文档查询的方法:var hasId = reply.replymsg.id(params.childid); 如果这个hasId为真。那就是在子文档中查到了这个childid 如果要update子文档。 目前只有一种办法 就是: if(hasId){ hasId.remove(); //或者reply.replymsg.pull({rid: params.childid}); } 然后再执行reply.replymsg.addToSet(新的对象是由原来的rid和其它不改变的值以及,新的update的值组成);
这个新的对象,也可以在前面把它查出来,把查到的值给这个新的对象,同时把要改变的比如:子文档中的rmsg设定为 你要update的值
});
感谢sogego的回复,我又仔细看了一遍官网和FAQ,现终于有点明白,做了个示例,供讨论。 官方FAQ文档
Model文件
DParent.js
var mongoose=require(‘mongoose’);
var Schema=mongoose.Schema;
var ObjectId = Schema.ObjectId;
var DChild=require(‘./DChild’);
var DParentSchema=new Schema({ msgbody:String, childs:[DChild.DChildSchema] });
mongoose.model('DParent’,DParentSchema);
DChild.js
var mongoose=require(‘mongoose’);
var Schema=mongoose.Schema;
var ObjectId = Schema.ObjectId;
var DChildSchema=new Schema({ parentid:ObjectId, childmsg:String, substrings:[String] });
exports.DChildSchema=DChildSchema; mongoose.model('DChild’,DChildSchema);
DUpdate.js
var models = require(‘…/models’);
var DParent = models.DParent;
var DChild = models.DChild;
exports.updateaction = function (req, res,next) {
// var dp=new DParent();
// dp.msgbody=’parent msg1’;
// var dchild0=new DChild();
// dchild0.parentid=dp._id;
// dchild0.childmsg=’children msg’;
// dchild0.substrings.push(‘str1’);
// dchild0.substrings.push(‘str2’);
// dchild0.substrings.push(‘str3’);
// dp.childs.push(dchild0);
// dp.save(function(err,result){
// res.send(‘’);
// return next();
// });
DParent.findOne({_id:’52e526f36dbf1d94255e39a8’}, function (err, dparent) {
if (err) {
console.log(‘Err:’ + err);
}
if (!dparent) {
console.log(‘no document’);
}
dchild0=dparent.childs[0];
dchild0.childmsg=’from parent’; //对于不是数组类型的字段直接通过这种方法来修改
// dchild0.substrings.splice(0,1); //在子文档child0的substrings这个数组中删除第一个记录
//dchild0.substrings.push(‘push22’); //在子文档child0的substrings这个数组中增加一个记录
//这种方式不行 dchild0.substrings[0]=’up0000’; //这种方法不能够修改数组中的值。。。。。。
dchild0.substrings.set(0,’updated by parent1’); //如要修改数组中的值,需用这个set方法,"0"表示要修改substrings数据的第1条记录
dparent.save(function(err,result){
if(err){
console.log(‘save error!’);
}
console.log(result);
res.send(‘’);
return next();
});
});
};
调用方法: var dts=require(‘./action/DUpdate’); server.get('/api_v1/ts’,dts.updateaction);
数据库结构:
{ “__v” : 10, “_id” : ObjectId(“52e526f36dbf1d94255e39a8”), “childs” : [{ “_id” : ObjectId(“52e526f36dbf1d94255e39a9”), “childmsg” : "from parent", “parentid” : ObjectId(“52e526f36dbf1d94255e39a8”), “substrings” : ["updated by parent1", "sub1", "sub2", “sub3”] }], “msgbody” : “parent msg1” }
还有忘记说一点,定义父类的Schema时,数组中的子类也要是子类的Schema,不能是子类的Model var DParentSchema=new Schema({ msgbody:String, childs:[DChild.DChildSchema] //不能定义成 childs:[DChild] ,这里DChild是Model,虽然大多数情况没问题,但遇到要更改数组中的值就不行了。 });