https://cnodejs.org/topic/50dde64ea7e6c6171a80a678
各位大神好,好久没写点什么东西了,最近也是cnode社区不知道咋的了都登录不进去,今天总算能回到这里,今天遇到这样的一个问题,发出来咨询下各位。 mongoose提供的schema/model/document想必大家都不陌生,model有一个update方法,现假设我的schema如下
//假设Schema对象已经从Mongoose的api中提取出来var schema =newSchema({
baseinfo:{
name:String,
age:Number},
status:Number});
如果数据库里已经存了这样的数据 {baseinfo:{name:'loong',age:20},status:0} 我现在要做这样的事情,只修改年龄。 我知道model的update方法支持mongodb原生的api,例如
//代码1
schemaModel.update({name:'loong'},{$set:{baseinfo:{age:26}}});
$setapi原本是支持有值覆盖/没值不改这一套模式(我称之为设置模式)的,即**$set后传入什么就修改什么,如果不传世不会被修改了,代码1中我没有传入status的修改,因此执行后在数据库的数据仍然是0。 但问题就来了,$set支持这的这模式对于层级只有一层的status很有用,但是对于有2个层级的baseinfo来说就不是这样的了。代码1最终运行的结果是age确实改为了26,但name属性却没有了。他的理解是将baseinfo:{age:26}这个键值对对应的覆盖(我称之为覆盖模式**)到实体上,理所当然的没有了name咯。 当然我在问问前我肯定是要做一番研究的,我从来不会做那种自己不研究就上来问问题的。那么我要研究的课题是:如何让mongoose的model支持多层级属性设置模式。在上例中,按照我所研究的课题就是,传什么,改什么,对于深层对象也做判断,永远没有覆盖。 于是,我决定采用深层**$set**,看是否能有所效果:
//代码2
schemaModel.update({name:'loong'},{$set:{baseinfo:{$set:{age:26}}}});
这时候,我在baseinfo后,age前又加了个**$set**,因为我觉得**$set**只查找一层,那么设置2个应该就能查找2层咯,但是结果返回错误,这时不被允许的。 再次查找api,尝试了使用如下的方式:
//代码3
schemaModel.update({name:'loong'},{$set:{‘baseinfo.age’:26}});
这时候是可以的,但是问题就来了:1.‘baseinfo.age’这样的写法是需要从json中转换的,麻烦,2.我要更新baseinfo下的多个数据,就要在这里写很多了。 有没有既不需要转换,同时又能解决多个数据的方式呢? 我再次看了看api,尝试了如下的方法:
//代码4
schemaModel.update({name:'loong'},{$set:{‘baseinfo.$’:{age:26}}});
这次代码是通过了,但是貌似并没有实现修改,这我就纳闷了,为什么会这样呢?查看了api,发现,对.$理解错了,他是针对数组的操作,如果有一个数组的匹配项,则做该项的更新。 ok,尝试了很多,发现都没有得到自己想要的结果,那我们就退一步吧,既然model无法实现,那么document能否实现呢?我的尝试仍然继续:
//代码5
schemaModel.findOne({name:'loong'},function(err,doc){
doc.set({baseinfo:{age:26}});
doc.save();});
一运行,这次真的成功了,name属性没有消失,而age属性也成功的修改了。 到此实验已经完成,我退而求其次的找到了解决问题的方法。但是我仍然很好奇,希望能有人提供线索帮忙解决以下2个问题: 1.能不能让model也能做到多层次的设置模式,而且要代码简单。 2.代码5如果baseinfo中还有多层的,不知道会不会出现类似代码1的问题,虽然实际中不会设置这么深的层次,但是还是作为一个问题,暂时没时间研究了,希望能有人测一下。
各位大神好,好久没写点什么东西了,最近也是cnode社区不知道咋的了都登录不进去,今天总算能回到这里,今天遇到这样的一个问题,发出来咨询下各位。 mongoose提供的schema/model/document想必大家都不陌生,model有一个update方法,现假设我的schema如下
//假设Schema对象已经从Mongoose的api中提取出来var schema =newSchema({
baseinfo:{
name:String,
age:Number},
status:Number});
如果数据库里已经存了这样的数据 {baseinfo:{name:'loong',age:20},status:0} 我现在要做这样的事情,只修改年龄。 我知道model的update方法支持mongodb原生的api,例如
//代码1
schemaModel.update({name:'loong'},{$set:{baseinfo:{age:26}}});
$setapi原本是支持有值覆盖/没值不改这一套模式(我称之为设置模式)的,即**$set后传入什么就修改什么,如果不传世不会被修改了,代码1中我没有传入status的修改,因此执行后在数据库的数据仍然是0。 但问题就来了,$set支持这的这模式对于层级只有一层的status很有用,但是对于有2个层级的baseinfo来说就不是这样的了。代码1最终运行的结果是age确实改为了26,但name属性却没有了。他的理解是将baseinfo:{age:26}这个键值对对应的覆盖(我称之为覆盖模式**)到实体上,理所当然的没有了name咯。 当然我在问问前我肯定是要做一番研究的,我从来不会做那种自己不研究就上来问问题的。那么我要研究的课题是:如何让mongoose的model支持多层级属性设置模式。在上例中,按照我所研究的课题就是,传什么,改什么,对于深层对象也做判断,永远没有覆盖。 于是,我决定采用深层**$set**,看是否能有所效果:
//代码2
schemaModel.update({name:'loong'},{$set:{baseinfo:{$set:{age:26}}}});
这时候,我在baseinfo后,age前又加了个**$set**,因为我觉得**$set**只查找一层,那么设置2个应该就能查找2层咯,但是结果返回错误,这时不被允许的。 再次查找api,尝试了使用如下的方式:
//代码3
schemaModel.update({name:'loong'},{$set:{‘baseinfo.age’:26}});
这时候是可以的,但是问题就来了:1.‘baseinfo.age’这样的写法是需要从json中转换的,麻烦,2.我要更新baseinfo下的多个数据,就要在这里写很多了。 有没有既不需要转换,同时又能解决多个数据的方式呢? 我再次看了看api,尝试了如下的方法:
//代码4
schemaModel.update({name:'loong'},{$set:{‘baseinfo.$’:{age:26}}});
这次代码是通过了,但是貌似并没有实现修改,这我就纳闷了,为什么会这样呢?查看了api,发现,对.$理解错了,他是针对数组的操作,如果有一个数组的匹配项,则做该项的更新。 ok,尝试了很多,发现都没有得到自己想要的结果,那我们就退一步吧,既然model无法实现,那么document能否实现呢?我的尝试仍然继续:
//代码5
schemaModel.findOne({name:'loong'},function(err,doc){
doc.set({baseinfo:{age:26}});
doc.save();});
一运行,这次真的成功了,name属性没有消失,而age属性也成功的修改了。 到此实验已经完成,我退而求其次的找到了解决问题的方法。但是我仍然很好奇,希望能有人提供线索帮忙解决以下2个问题: 1.能不能让model也能做到多层次的设置模式,而且要代码简单。 2.代码5如果baseinfo中还有多层的,不知道会不会出现类似代码1的问题,虽然实际中不会设置这么深的层次,但是还是作为一个问题,暂时没时间研究了,希望能有人测一下。