设为首页 收藏本站
查看: 1351|回复: 0

[经验分享] MongoDB使用$set和$inc修改器更新数据

[复制链接]

尚未签到

发表于 2018-10-28 06:05:19 | 显示全部楼层 |阅读模式
前面我们实验了用update方法来更新一个文档,我们发现,通常一个文档只会有一小部分需要更新,这时候如果我们把新的文档全部写下来做为update方法的第二个参数,显得很啰嗦很麻烦,特别是文档比较复杂的时候.而利用原子的更新修改器,可以使得这种部分的更新极为方便,高效.更新修改器是种特殊的键,用来指定复杂的更新操作,比如调整,增加或者删除键,还可能是操作数组或者内嵌文档.下面,我们来实验下几种常用的更新修改器.  首先是$set和$unset.
  $set用来指定一个键的值.如果这个键存在,就修改它;不存在,就创建它.
  > db.name.find()
  { "_id" : ObjectId("505a5925f67c1b9a341caefb"), "fname" : "jeff", "lname" : "jiang" }
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$set:{"fname" : "jeffery"}})
  > db.name.find()
  { "_id" : ObjectId("505a5925f67c1b9a341caefb"), "fname" : "jeffery", "lname" : "jiang" }
  可以看到,原文档的"fname"是存在的,所以$set修改器只修改了它的值("jeff"-->"jeffery")
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$set:{age:23}})
  > db.name.find()
  { "_id" : ObjectId("505a5925f67c1b9a341caefb"), "age" : 23, "fname" : "jeffery", "lname" : "jiang" }
  而在这里,原文档中是没有"age"这个键的,修改器创建了它.可是,问题来了,它怎么插到了这里,这和我理想中的不一样,我是希望它插入到文档的最后的.是不是因为我用"_id"查找文档,然后它就插入到了"_id"的后面呢.那么,如果我用文档的最后那个键"lname"来查找文档,它是不是会插入到新文档的最后呢?我们实验一下:
  > db.name.find()
  { "_id" : ObjectId("505a5925f67c1b9a341caefb"), "fname" : "jeffery", "lname" : "jiang" }
  > db.name.update({"lname" : "jiang"},{$set:{age:23}})
  > db.name.find()
  { "_id" : ObjectId("505a5925f67c1b9a341caefb"), "age" : 23, "fname" : "jeffery", "lname" : "jiang" }
  还是插入到了原来的位置,我们的猜想是错误的.那么,我们一定要把它插入到文档的最后怎么办呢.我目前只知道一种最原始的办法.
  > db.name.find()
  { "_id" : ObjectId("505a5925f67c1b9a341caefb"), "fname" : "jeffery", "lname" : "jiang" }
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{"fname" : "jeffery", "lname" : "jiang",age:23})
  > db.name.find()
  { "_id" : ObjectId("505a5925f67c1b9a341caefb"), "fname" : "jeffery", "lname" : "jiang", "age" : 23 }
  这应该是最笨的方法了,如果有高手,望不吝赐教。
  > db.name.find()
  { "_id" : ObjectId("505a5925f67c1b9a341caefb"), "fname" : "jeffery", "lname" : "jiang", "age" : 23, "favorite" : "reading" }
  用$set可以修改键的数据类型。例如的的爱好不会只有一种,像我这样没爱好的,也能说出个两三个来。那么,我们可以将上面普通的“favorite”键的值变成一个数组:
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$set:{favorite:"reading","swimming","surfing the Insternet","listening to music"]}})
  > db.name.find()
  { "_id" : ObjectId("505a5925f67c1b9a341caefb"), "age" : 23, "favorite" : [ "reading", "swimming", "surfing the Insternet", "listening to music" ], "fname" : "jeffery", "lname" : "jiang" }
  真是头疼,修改后,文档的顺序结构也变了,这里先不管了。我们用findOne()可能看得清楚一些:
  > db.name.findOne()
  {
  "_id" : ObjectId("505a5925f67c1b9a341caefb"),
  "age" : 23,
  "favorite" : [
  "reading",
  "swimming",
  "surfing the Insternet",
  "listening to music"
  ],
  "fname" : "jeffery",
  "lname" : "jiang"
  }
  上面我们将普通的“favorite”键的值变成了一个数组,这里我们再将数组变为文档:
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$set:{favorite:{1:"reading",2:"swimming",3:"surfing the Insternet",4:"listening to music"}}})
  > db.name.findOne()
  {
  "_id" : ObjectId("505a5925f67c1b9a341caefb"),
  "age" : 23,
  "favorite" : {
  "1" : "reading",
  "2" : "swimming",
  "3" : "surfing the Insternet",
  "4" : "listening to music"
  },
  "fname" : "jeffery",
  "lname" : "jiang"
  }
  现在我们有内嵌文档了,用$set也可以来修改内嵌文档,它的用法就像针对普通文档一样。下面我想再添加一个爱好,我觉得打乒乓球很不错,来简单实验下:
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$set:{"favorite.5":"playing Ping-Pong"}})
  > db.name.findOne()
  {
  "_id" : ObjectId("505a5925f67c1b9a341caefb"),
  "age" : 23,
  "favorite" : {
  "1" : "reading",
  "2" : "swimming",
  "3" : "surfing the Insternet",
  "4" : "listening to music",
  "5" : "playing Ping-Pong"
  },
  "fname" : "jeffery",
  "lname" : "jiang"
  }
  可是,我又觉得,打乒乓没有打篮球帅,我想把其中一个爱好改成打篮球,也很简单:
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$set:{"favorite.5":"playing basketball"}})
  > db.name.findOne()
  {
  "_id" : ObjectId("505a5925f67c1b9a341caefb"),
  "age" : 23,
  "favorite" : {
  "1" : "reading",
  "2" : "swimming",
  "3" : "surfing the Insternet",
  "4" : "listening to music",
  "5" : "playing basketball"
  },
  "fname" : "jeffery",
  "lname" : "jiang"
  }
  $set的基本用法差不多实验完了,下面来看看$unset。从名字就可以看出,它们两是一对。前者是来修改键,后者用来删除键。$unset也可以修改普通文档和内嵌文档。这里我用它来修改内嵌文档。像游泳这种爱好,一年难得一两次的,我想把它从爱好里删除,怎么操作呢?简单看一下:
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$unset:{"favorite.2":1}})
  > db.name.findOne()
  {
  "_id" : ObjectId("505a5925f67c1b9a341caefb"),
  "age" : 23,
  "favorite" : {
  "1" : "reading",
  "3" : "surfing the Insternet",
  "4" : "listening to music",
  "5" : "playing basketball"
  },
  "fname" : "jeffery",
  "lname" : "jiang"
  }
  下面,我们来学习一下另一个修改器。今年,哥23岁了,再过不到两个月,就要24岁了。如果现在我想增加年龄,虽然$set修改器可以达到这个目的,但这里我想要用另外一个:$inc修改器。它用来增加已有键的值,或者在键不存在时创建一个键。这在有变化数值的地方,使用起来非常方便。一转眼几个月过去了,我24了,下面来修改数据:
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$inc:{age:1}})
  > db.name.findOne()
  {
  "_id" : ObjectId("505a5925f67c1b9a341caefb"),
  "age" : 24,
  "favorite" : {
  "1" : "reading",
  "3" : "surfing the Insternet",
  "4" : "listening to music",
  "5" : "playing basketball"
  },
  "fname" : "jeffery",
  "lname" : "jiang"
  }
  世界那么大,理想那么小,而我那小小的理想目前还不曾实现,这时间又匆匆地过了,压力各种大啊。看,只要那么一下,又过了6年。30可是人生的分水领,不能再这么没出息了,不然一辈子也就这样了:
  db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$inc:{age:6}})
  > db.name.findOne()
  {
  "_id" : ObjectId("505a5925f67c1b9a341caefb"),
  "age" : 30,
  "favorite" : {
  "1" : "reading",
  "3" : "surfing the Insternet",
  "4" : "listening to music",
  "5" : "playing basketball"
  },
  "fname" : "jeffery",
  "lname" : "jiang"
  }
  以上是键存在的情况,存在就修改;那么键不存在呢?上面我们说了,不存在就创建。哥试着把哥的身高添进去,这是个很艰难的决定。就哥这身高,穿上鞋子都不够170的,遇到赤脚的女神都得仰望,我说不自卑,你信么?
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$inc:{height:166}})
  > db.name.findOne()
  {
  "_id" : ObjectId("505a5925f67c1b9a341caefb"),
  "age" : 30,
  "favorite" : {
  "1" : "reading",
  "3" : "surfing the Insternet",
  "4" : "listening to music",
  "5" : "playing basketball"
  },
  "fname" : "jeffery",
  "height" : 166,
  "lname" : "jiang"
  }
  还好哥才活了23年,到30岁,还能肆无忌惮地奋斗6、7年。希望能混出点名堂。其实我想说的是,$inc修改器不止能增加数字,它也能用来减少。下面我们来操作一下:
  > db.name.update({"_id" : ObjectId("505a5925f67c1b9a341caefb")},{$inc:{age:-7}})
  > db.name.findOne()
  {
  "_id" : ObjectId("505a5925f67c1b9a341caefb"),
  "age" : 23,
  "favorite" : {
  "1" : "reading",
  "3" : "surfing the Insternet",
  "4" : "listening to music",
  "5" : "playing basketball"
  },
  "fname" : "jeffery",
  "height" : 166,
  "lname" : "jiang"
  }
  总之,你想怎么修改数据,就给$inc传递一个不同的值就好了。但是,$inc只能用于整数、长整数和双精度浮点数。要是其他类型应该使用$set修改器或其他修改器。还有,在使用修改器时,“_id”的值是不能改变的,但使用整个文档替换时是可以改变的。其他键值,包括其他唯一索引的键都是可以修改的。$set和$inc用来修改标量值。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-627237-1-1.html 上篇帖子: MongoDB修改数据update和save方法 下篇帖子: Mongodb 基本安装配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表