设为首页 收藏本站
查看: 1173|回复: 1

[经验分享] MongoDB 文档字段增删改

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-8-21 10:00:55 | 显示全部楼层 |阅读模式
MongoDB 基于CRUD(create,read,update,delete)方式实现了对集合上的文档进行增删改查。对于集合上字段的增删改,可以使用set或者unset修改器来实现。也可以使用文档替换的方式来实现。本文主要描述集合上字段的增删改,以及基于选项upsert的更新。
a.语法描述   db.collection.update(
      <query>,                  //查询或过滤条件
      <update>,                 //修改器(被修改键及内容)
      {                        
        upsert: <boolean>,      //为true或者false,如果为true,未找到匹配文档则创建新文档
        multi: <boolean>,       //用于确定是单行还是更新所有行(true为所有行)
        writeConcern: <document>  //设定写关注,用于确保强一致性还是弱一致性
      }                            //后面的3.2之后的语法参数基本相同
   )
其他的如updateOne,updateMany等用法请参考:MongoDB 文档更新
MongoDB集合上所有的写操作特性
原子性操作(单个文档级别原子性操作)
_id 字段无法修改,即无法使用一个新的_id值来代替
由于更新导致文档尺寸超出预期分配的情形,会自动调整填充因子,重新分配空间
保留文档字段的顺序,但是更新或重命名可能导致字段顺序重新排序(_id总是文档第一个字段)
update的几个常用修改器:
//$set修改器最常用,等同于RDBMSupdate的set子句
b.使用$set修改器修改年龄字段> db.chenji.update({name:"李旭"},{$set:{"年龄":24}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })

> db.chenji.find({$or:[{name:"李旭"}]})
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "年纪" : "三年级",
       "年龄" : 24
}
> db.chenji.find({$or:[{name:"李旭"},{"年龄":24}]})
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "年纪" : "三年级",
       "年龄" : 24
}

c. 文档新增字段($set实现)> db.chenji.update({name:"李旭"},{$set:{add:"sex"}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"},{"年龄":24}]})
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "年纪" : "三年级",
       "年龄" : 24,
       "add" : "sex"

查看新增字段add
> db.chenji.find({name:"李旭"},{"_id":0,"年纪":1,"年龄":1,add:1})
{ "年纪" : "三年级","年龄" : 24, "add" : "sex" }
d.文档删除字段字段的删除方法为{"$unset":{field_name:1}}
> db.chenji.update({name:"李旭"},{"$unset":{add:1}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "年纪" : "三年级",
       "年龄" : 24
}
> db.chenji.find({name:"李旭"},{"_id":0,"年纪":1,"年龄":1,add:1})
{ "年纪" : "三年级","年龄" : 24 }

删除年龄字段:
> db.chenji.update({name:"李旭"},{"$unset":{"年龄":1}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "年纪" : "三年级"
}
删除年纪字段:

> db.chenji.update({name:"李旭"},{"$unset":{"年纪":1}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{ "_id" :ObjectId("59987eee7cd6cda607043cd1"), "name" : "李旭"}
>

添加字段:age和年龄

> db.chenji.update({name:"李旭"},{$set:{"年级":"一年级"}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.update({name:"李旭"},{$set:{"age":9}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "age" : 9,
       "年级" : "一年级"
}

e.字段值的增加或减少当使用$inc修改器时,当字段不存在时,会自动创建该字段,如果存在,则在原有值的基础上进行增加或者减少
//$inc主要是用于专门进行数字的增加或减少,因此$inc只能用于整型,长整形,或者双精度浮点型的值
//$inc不支持字符串,数组以及其他非数字的值
//注,对于$inc的操作,$set也可以完成。$inc存在的理由是$inc更高效

> db.chenji.update({name:"李旭"},{$inc:{num:100}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "age" : 9,
       "年级" : "一年级",
       "num" : 100
}
再次update这个num字段会和第一次的100增加101
> db.chenji.update({name:"李旭"},{$inc:{num:101}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "age" : 9,
        "年级" : "一年级",
       "num" : 201
}

基于$inc的负值:
> db.chenji.update({name:"李旭"},{$inc:{num:-100}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]}).pretty()
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "age" : 9,
       "年级" : "一年级",
       "num" : 101
}
> db.chenji.update({name:"李旭"},{$inc:{num:-50}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]}).pretty()
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "age" : 9,
       "年级" : "一年级",
       "num" : 51


下面使用非数字来实现$inc,报错如下:
db.chenji.update({name:"李旭"},{$inc:{num:"1ab"}})
WriteResult({
       "nMatched" : 0,
       "nUpserted" : 0,
       "nModified" : 0,
       "writeError" : {
               "code" : 14,
               "errmsg" : "Cannot increment with non-numeric argument:{num: \"1ab\"}"
        }
})

f. 时间戳字段的增加及自动更新($currentDate)
> db.chenji.update({name:"李旭"},{$inc:{num:60},$currentDate:{lastModified:true}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]}).pretty()
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "name" : "李旭",
       "age" : 9,
       "年级" : "一年级",
       "num" : 231,
       "lastModified" : ISODate("2017-08-20T08:39:53.601Z")
}

f.文档字段重命名($rename)> db.chenji.update({name:"李旭"},{$rename:{"name":"ename"}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]}).pretty()
> db.chenji.find({$or:[{ename:"李旭"}]}).pretty()
{
       "_id" : ObjectId("59987eee7cd6cda607043cd1"),
       "age" : 9,
       "年级" : "一年级",
       "num" : 231,
       "lastModified" :ISODate("2017-08-20T08:39:53.601Z"),
       "ename" : "李旭"
}
> db.chenji.find({ename:"李旭"},{"_id":0,ename:1})
{ "ename" : "李旭"}


对整个集合上所有文档字段进行重命名:
>db.chenji.update({},{$rename:{"name":"ename"}},{multi:true})
WriteResult({ "nMatched" : 7,"nUpserted" : 0, "nModified" : 6 }) /此次修改为11条,因为前面以及修改过1条
> db.chenji.find();
{ "_id" :ObjectId("59990ec402730a37fe1ee79e"), "年纪": "二年级", "年龄" : "12", "ename" :"建伟" }
{ "_id" :ObjectId("59987eee7cd6cda607043cd1"), "age" : 9, "年级": "一年级", "num" : 231, "lastModified" :ISODate("2017-08-20T08:39:53.601Z"), "ename" : "李旭"}
{ "_id" :ObjectId("5998860a7cd6cda607043cd2"), "年纪": "三年级", "年龄" : "14", "ename" :"张三" }
{ "_id" :ObjectId("599886227cd6cda607043cd3"), "年纪": "四年级", "年龄" : "16", "ename" :"王三" }
{ "_id" :ObjectId("599886357cd6cda607043cd4"), "年纪": "一年级", "年龄" : "8", "ename" :"王七" }
{ "_id" :ObjectId("599886537cd6cda607043cd5"), "年纪": "一年级", "年龄" : "9", "ename" :"张巴" }
{ "_id" :ObjectId("5998866e7cd6cda607043cd6"), "年纪": "七年级", "年龄" : "16", "ename" :"谢娜" }
>

g.upsert选项用法/ upsert相当于oracle的merge into或者mysql中的replaceinto
// upsert即是当集合中匹配到满足条件的文档时,则更新文档,否则则是新增文档。前提是该选项的值为true,缺省为flase。

> //下面的演示的是匹配到文档时的例子
小结:
a、对于文档上数据的修改有多种方式(修改器),常用的为$set修改器以及$inc
b、$inc是一种高效的数据修改器,通常用于实现数值的增加或减少,仅支持数据类型。
c、对于文档字段的增加,可以使用$set,$unset,$inc,$currentDate等方式
d、对于文档字段的删除,使用$unset方式来实现
e、upsert选项可以实现匹配的文档则更新,不匹配时则插入


运维网声明 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-403195-1-1.html 上篇帖子: MongoDB查询集合中的文档 下篇帖子: mongodb客户端连接工具mongobooster
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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