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的问题,虽然实际中不会设置这么深的层次,但是还是作为一个问题,暂时没时间研究了,希望能有人测一下。

6 回复

我觉得model直接改得好处,少了一步save()!但是第二种更自然点,找到这个文件,直接对文件下的key赋值,在保存下,也很简单啊!即使多层,可以一直.下去(数组除外)

schemaModel.findOne({name:'loong'},function(err,doc){
doc.baseinfo.age=26;
doc.save();});
 

你的问题应该是直接对文档里的某一个内嵌文档的属性做修改,而不破坏整个文档吧,我一般用原生的mongo-native,展示给你看下:

[root@centos6998 ~]# mongoMongoDB shell version:2.2.2
connecting to: test
db.testcol.insert({info:{name:123,age:123,sex:"male"},id:1,weight:0})> db.testcol.find(){"_id":ObjectId("50de94734af5ea426ff2f77b"),"info":{"name":123,"age":123,"sex":"male"},"id":1,"weight":0}> db.testcol.update({id:1},{$set:{"info.name":0}})> db.testcol.find(){"_id":ObjectId("50de94734af5ea426ff2f77b"),"info":{"name":0,"age":123,"sex":"male"},"id":1,"weight":0}
 

@snoopy 吴哥的代码形同我的代码3,这个的确是可以,但是问题在于我上面提过的 1.需要将json嵌套转换为字符串.连接格式 2.如果我要更新的数据比较多的时候,就要手动写很多 按照你的例子,如果我要修改name和age,就要

db.testcol.update({id:1},{$set:{"info.name":0,"info.age":25}})//要将前端传过来的json: {info:{name:0,age:25}} 转换为{"info.name":0,"info.age":25}
 

火钳刘明

 
var age, data, id, name;

id = req.query.id;

name = req.query.name;

age = req.query.age;

data ={
name:  name,
age: age
}; model.findOneAndUpdate({
_id: id
}, data,null,function(err, results){if(err){return res.json(500, err);}#在此操作代码});
 

用点语法,

//你的代码1
schemaModel.update({name:'loong'},{$set:{"baseinfo.age":26}});//字段名加引号保险些,有时候不加引号会有问题,也搞不清楚什么时候有问题

另外再问你个问题啊,那个mongoose链接在整个项目里只可以有一个链接,那如果项目太大,进行数据操作的地方太多,那怎么办,虽然schema什么的都可以在外面定义,但是db.once(“open”,function(){}),所有的数据操作都在回调里,那会很乱的吧。。。有什么比较官方的解决办法吗?

mongoose深层修改问题的更多相关文章

  1. 校园网IPv6加速

    对于广大学生来说,上网是一件很纠结的事情,校园网要么按时间计费,要么按流量计费,要么是校园宽带.按时间计费速度慢,按流量计费费用高,校园宽带还不能共享,只能电脑开热点给手机上网.有没有既能提高网速又经 ...

  2. Express+MongoDB开发web后台接口MongoDB

    摘要: Express开发web接口; 安装MongoDB,启动.连接MongoDB服务台; 使用nodejs和mongoose模块链接和操作MongoDB; 一.Express开发web接口 exp ...

  3. Express+Nodejs 下的登录拦截实现

    Express+Nodejs 下的登录拦截实现 利用商城举例,在商城中没有登录之前,可以看商品列表.详情.登录或者注册都可以,但是购买的时候是不行的,那么这个功能在Node后台中是怎么实现的呢,这个功 ...

  4. C++中extern “C”含义深层探索(在原作的基础上修改) .

    1. 引言 C++ 语言的创建初衷是“a better C” ,但是这并不意味着C++ 中类似C 语言的全局变量和函数所采用的编译和连接方式与C 语言完全相同.作为一种欲与C 兼容的语言,C++ 保留 ...

  5. React中setState如何修改深层对象?

    在React中经常会使用到setState,因为在react生态中,state就是一切.在开发过程中,时长会在state中遇到一些比较复杂的数据结构,类似下面这样的: 这时需要我们修改list中obj ...

  6. mongoose返回值无法修改

    mongoose 查询方法 find 例:db.collections.find(query,function(err,doc) { 如果var res = doc[0]  是{name:'feife ...

  7. mongoose修改数组中某个特定的值

    写博客的时候有一个这样的业务,一个标签集合和一个文章集合,它们是多对多的关系,文章集合中tags字段包含它对应的标签,现在修改标签集合中某条标签记录的名字,文章集合中所有包含这个标签的tags字段的值 ...

  8. mongoose - 让node.js高效操作mongodb

    Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,类似ORM,Mongoose将数据库中的数据转换为JavaScript对象以供你在应用中使用. ...

  9. Mongo基础使用,以及在Express项目中使用Mongoose

    MongoDB的基本使用 MongoDB特点: 使用BSON存储数据 支持相对丰富的查询操作(相对其他nosql数据库) 支持索引 副本集(支持多个实例/多个服务器运行同个数据库) 分片(数据库水平扩 ...

随机推荐

  1. (九)uboot配置编译、源码分析

    一.X210官方uboot配置编译实践1.找到官方移植好的uboot(BSP概念)(1)源头的源代码是uboot官网下载的.这个下载的源代码可能没有你当前使用的开发板的移植,甚至找不到当前开发板使用的 ...

  2. Poco C++——HTTP的post请求和get请求

    两种请求都需要包含头文件: #include <iostream> #include <string> #include "Poco/Net/HTTPClientSe ...

  3. WCF配置详解

    前面一篇文章<WCF 学习总结1 -- 简单实例> 一股脑儿展示了几种WCF部署方式,其中配置文件(App.config/Web.config)都是IDE自动生成,省去了我们不少功夫.现在 ...

  4. 使用react native for android生成app

    参考文章 http://reactnative.cn/docs/getting-started.html http://www.lcode.org/react-native/ https://gith ...

  5. WCF技术剖析之二:再谈IIS与ASP.NET管道

    原文地址:http://www.cnblogs.com/artech/archive/2009/06/20/1507165.html 在2007年9月份,我曾经写了三篇详细介绍IIS架构和ASP.NE ...

  6. 修改IIS文件上传大小限制

    如果要上传的文件比较大,则需在IIS中修改文件上传的大小限制,否则无法上传(表现为程序不报错,而上传进度到100%后没有反应). 点击"管理"下的"配置编辑器" ...

  7. js中的apply和call API

    借用网上的一个例子: fun.call(this,arg1,arg2,arg3) fun.apply(this,arguments) this.fun(arg1,arg2,arg3) 三种方法等效. ...

  8. python 练习 5

    #!/usr/bin/python # -*- coding: utf-8 -*- from collections import deque def z69(): '''猜牌术(1) 魔术师,最上面 ...

  9. [hadoop] 集群启动和内存调优

    1.启动Hadoop集群 #首先查看下zoo.cfg里面配置的server.id和集群主机的id是否一致 #如果不一致会造成yarn控制不了从节点的启动 cat /home/hadoop/zookee ...

  10. python中的异常处理

    主要用到 try...except...raise...finally... 1. try...except... try: for i in range(1, 1000): print i time ...