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

[经验分享] 03.Mongodb创建、更新和删除文档。

[复制链接]

尚未签到

发表于 2018-10-26 11:53:42 | 显示全部楼层 |阅读模式
  插入:
  >db.collectionName.insert({"bar":"baz")}
  批量插入:
  如果要向集合插入多个文档,使用批量插入会快一些。
  batchInsert函数实现批量插入,它接受一个文档数组作为参数。
  >db.collectionName.batchInsert([ {"_id:0}, {"_id":1}, {"_id":2} ])
  >db.collectionName.find()
  {"_id:0}
  {"_id":1}
  {"_id":2}
  删除文档:
  >db.collectionName.remove({})
  上述命令只删除集合里面的文档,并不会删除集合本身,也不会删除集合的元信息。
  remove函数可以接受一个查询文档作为限定条件作为可选参数。给定参数后,符合条件的文档才会被删除。
  >db.collectionName.remove({"xxxx":true})
  删除数据是永久性的,不能撤销,也不能恢复。
  删除速度:
  删除文档通常很快,但是如果要清空集合,使用drop直接删除集合会更快。
  例如,插入测试数据:
  >for (var i=0; i < 1000000; i++) {
  ... db.tmps.insert({"foo":i})
  ... }
  使用remove删除,并记录花费时间:
  var timeRemoves = function() {
  var start = (new Date()).getTime();
  db.tmps.remove({});
  db.tmps.findOne();//Make sure the remove finishes before continuing
  var timeDiff = (new Date()).getTime() - start;
  print("Remove took:"+timeDiff+"ms");
  }
  更新文档:
  db.collection.update(
  ,
  ,
  {
  upsert: ,
  multi: ,
  writeConcern:
  }
  )
  update有两个参数,一个是查询文档,用于定位需要更新的文档,另一个是修改器(modifier)文档,用于说明要对找到的文档进行哪些修改。
  更新操作是不可分割的:若是两个更新同时发生,先到达服务器的先执行,接着执行令一个。
  ·文档替换:
  最简单的更新就是用一个新文档完全替换匹配的文档。这适用于进行大规模式迁移的情况。
  例:
  默认文档结构:
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f125773d3fab4bb9d6dc63"),
  "Name" : "joe",
  "Friends" : 32,
  "Enemies" : 2,
  "Date" : ISODate("2015-02-28T02:18:21.858Z")
  }
  写一个definetmps.js文档,内容如下:
  var replaceupdate = function(){
  db.tmps.findOne();
  var joe = db.tmps.findOne({"Name":"joe"});
  joe.relationships = {"Friends":joe.Friends,"Enemies":joe.Enemies};
  joe.Username = joe.Name;
  delete joe.Friends;
  delete joe.Enemies;
  delete joe.Name;
  db.tmps.update({"Name":"joe"},joe);
  db.tmps.findOne();
  }
  然后再Shell中加载,并执行函数replaceupdate(),最后验证文档结构:
  >load("definetmps.js")
  true
  >replaceupdate()
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f125773d3fab4bb9d6dc63"),
  "Date" : ISODate("2015-02-28T02:18:21.858Z"),
  "relationships" : {
  "Friends" : 32,
  "Enemies" : 2
  },
  "Username" : "joe"
  }
  一个常见的错误是查询条件匹配到了多个文档,然后更新时由于第二个参数存在就产生重复的"_id"值。数据库就会抛出错误,任何文档都不会更新。
  ·使用修改器:
  通常文档只会有一部分要更新。可以使用原子性的更新修改器,指定对文档中的某些字段进行更新。
  1."$set"修改器入门:
  "$set"用来指定一个字段的值。如果这个字段不存在,则创建它。这对更新模式或增加用户自定义键来说非常方便。
  例:存储用户资料的文档,结构如下,
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 32,
  "sex" : "male",
  "location" : "Wisconsin"
  }
  我们要添加一个新键,用户喜欢的书籍进去,可以使用"$set":
  >db.tmps.update({"_id" : ObjectId("54f131d0f755cba4f8d7cb2a")},
  ... {"$set" : {"favorite book" : "war and peace"}})
  然后我们文档就有了新键:
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 32,
  "sex" : "male",
  "location" : "Wisconsin",
  "favorite book" : "war and peace"
  }
  这个时候喜欢书的键已经存在了,用户想换一本,可直接通过$set完成更新。
  用"$set"甚至可以修改键的类型。例如用户喜欢很多本书,就可以将"favorite book"键值变成一个数组:
  >db.tmps.update({"_id" : ObjectId("54f131d0f755cba4f8d7cb2a")},
  ... {"$set" : {"favorite book" : ["book1","book2","book3"]}})
  如果用户不喜欢读书,可以用"$unset"将这个键值完全删除。
  >db.tmps.update({"_id" : ObjectId("54f131d0f755cba4f8d7cb2a")},
  ... {"$unset" : {"favorite book" : 1}})
  也可以用"$set"修改内嵌文档:
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 32,
  "sex" : "male",
  "location" : "Wisconsin",
  "contact" : {
  "email" : "123@qq.com",
  "pnum" : "13212342112"
  }
  }
  >db.tmps.update({"name":"joe"},
  ... {"$set":{"contact.email":"1450327195@qq.com"}})
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 32,
  "sex" : "male",
  "location" : "Wisconsin",
  "contact" : {
  "email" : "1450327195@qq.com",
  "pnum" : "13212342112"
  }
  }
  2.增加和减少"$inc"
  "$inc"修改器用来增加已有键的值,改键不存在就会创建一个。
  "$inc"与"$set"的用法类似,就是专门用来增加和减少数字的。"$inc"只能用于整形、长整形或双精度浮点型的值。
  >db.tmps.update({"name":"joe"},
  ... {"$inc":{"age":1}})
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 33,
  "sex" : "male",
  "location" : "Wisconsin",
  "contact" : {
  "email" : "1450327195@qq.com",
  "pnum" : "13212342112"
  }
  }
  3.数组修改器
  有一大类很重要的修改器可用于操作数组。数组是常用且非常有用的数据结构:它们不仅是可通过索引进行引用的列表,而且还可以作为数据集(set)来用。
  4.添加元素"$push"
  如果数组已经存在,"$push"会向已有数组末尾添加一个元素,没有则创建一个新数组。
  如:
  >db.tmps.update({"name":"joe"},
  ... {"$push":{"comments":{"name":"bob","email":"bob@qq.com"}}})
  还添加继续使用"$push",这是一种比较简单的"$push"使用形式,也可以将它应用在一些比较复杂的数组操作中。
  使用"$each"子操作符,可以通过一次"$push"操作添加多个值。
  db.tmps.update({"name":"joe"},
  ... {"$push":{"comments":{"$each":[{"name":"bob","email":"bob@qq.com"},{"name":"carlo","email":"carlo@qq.com"}]}}})
  PS:通过"$set"的实现:
  >db.tmps.update({"name":"joe"},
  ... {"$set":{"comments":[{"name":"bob","email":"bob@qq.com"},{"name":"carlo","email":"carlo@qq.com"}]}})
  如果希望数组的最大长度是固定的,那么可以将"$slice"和"$push"组合在一起使用,这样就可以保证数组不会超出设定好的最大长度,这实际上就得到了一个最多包含N个元素的数组。
  >db.tmps.update({"name":"joe"},
  ... {"$push":{"favoritetop":{
  ...   "$each":[{"name":"book","level":3},
  ...            {"name":"music","level":1},
  ...            {"name":"movie","level":4},
  ...            {"name":"run","level":2}],
  ...   "$slice":-3,
  ...   "$sort":{"level":-1}}}})
  注意:不能只将"slice"或者"$sort"与"$push"配合使用,且必须使用"$each"。
  5.将数组作为数据集使用
  如果将数组作为数据集使用,保证数组元素不会重复。可以在查询文档中用"$ne"来实现。
  (test)>db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 43,
  "emails" : [
  "aa@qq.com",
  "bb@qq.com",
  "cc@qq.com"
  ]
  }
  >db.tmps.update({"emails":{"$ne":"aa@qq.com"}}, {"$push":{"emails":"aa@qq.com"}})
  WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
  >db.tmps.update({"emails":{"$ne":"dd@qq.com"}}, {"$push":{"emails":"a@qq.com"}})
  WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
  由这里可以看出,$ne是在查询中做判断的,如果判断内容不存在则执行后面的$push操作。
  也可以用"$addToSet"来实现:
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 43,
  "emails" : [
  "aa@qq.com",
  "bb@qq.com",
  "cc@qq.com"
  ]
  }
  >db.tmps.update({"name":"joe"},
  ... {"$addToSet":{"emails":"aa@qq.com"}})
  WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
  >db.tmps.update({"name":"joe"},
  ... {"$addToSet":{"emails":"dd@qq.com"}})
  WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
  (test)>db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 43,
  "emails" : [
  "aa@qq.com",
  "bb@qq.com",
  "cc@qq.com",
  "dd@qq.com"
  ]
  }
  将"$addToSet"和"$each"组合起来,可以添加多个不同的值,而使用"$ne"和"$push"组合则不能实现。
  >db.tmps.update({"name":"joe"},
  ... {"$addToSet":{"emails":{"$each":[
  ... "a@qq.com","b@qq.com","c@qq.com","d@qq.com"]}}})
  6.删除元素
  有几个从数组中删除元素的方法。若是把数组看成队列或者栈,可以用"$pop"这个修改器从数组任何一端删除元素。
  >db.tmps.update({"name":"joe"},
  ... {"$pop":{"emails":1}})    //从数组末尾删除元素。
  >db.tmps.update({"name":"joe"}, {"$pop":{"emails":-1}})   //从数组开头删除元素。
  有时需要基于特定条件来删除元素,而不仅仅是依据元素位置,这时可以用"$pull"。它会将所有匹配文档全部删除,而不是只删除一个。对数组[1,1,2,1]执行pull 1,结果就只剩一个元素的数组[2]。
  7.基于位置的数组修改器
  通过位置或者定位操作符("$"):
  数组下标都是以0开始的,可以将下标直接作为建来选择元素。
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 43,
  "emails" : [
  "bb@qq.com",
  "cc@qq.com",
  "dd@qq.com",
  "a@qq.com",
  "b@qq.com",
  "c@qq.com"
  ]
  }
  >db.tmps.update({"name":"joe"},
  ... {"$set":{"emails.3":"aa@qq.com"}})
  WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 43,
  "emails" : [
  "bb@qq.com",
  "cc@qq.com",
  "dd@qq.com",
  "aa@qq.com",
  "b@qq.com",
  "c@qq.com"
  ]
  }
  很多情况下,不预先查询文档就不能知道要修改数组的下标,为了解决这个问题,Mongodb提供了定位操作符"$",用来定位查询已经匹配的数组元素,并进行更新。如下:
  >db.blog.findOne()
  {
  "_id" : ObjectId("54f56483d9c146390ce21c58"),
  "title" : "my frist blog.",
  "content" : "a b c d e f g ....",
  "comments" : [
  {
  "comment" : "good",
  "author" : "joe",
  "votes" : 0
  },
  {
  "comment" : "it's ok",
  "author" : "john",
  "votes" : 2
  }
  ]
  }
  >db.blog.update({"comments.author":"joe"},
  ... {"$set":{"comments.$.author":"jim"}})
  WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
  >db.blog.findOne()
  {
  "_id" : ObjectId("54f56483d9c146390ce21c58"),
  "title" : "my frist blog.",
  "content" : "a b c d e f g ....",
  "comments" : [
  {
  "comment" : "good",
  "author" : "jim",
  "votes" : 0
  },
  {
  "comment" : "it's ok",
  "author" : "john",
  "votes" : 2
  }
  ]
  }
  注意,定位符只更新第一个匹配元素。
  特殊的更新:upsert
  upsert更新,要是没有找到符合更新条件的文档,就会以这个条件和更新文档为基础创建一个新的文档。如果找到匹配文档,则正常更新。
  update操作的第三个参数处为true,则是upsert更新!
  db.test.update({"url":"www.example.com"}, {"$inc":{"pageviews":1}},true)    // 此为简写
  db.test.update({"url":"www.example.com"}, {"$inc":{"pageviews":1}},{upsert:true})
  save函数:
  使用save函数时,如果文档不存在,它会自动创建文档;如果文档存在,它就更新这个文档。它只有一个参数:文档。如果这个文档有"_id"键,save会调用upsert;否则调用insert。
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 43,
  "emails" : [
  "bb@qq.com",
  "cc@qq.com",
  "dd@qq.com",
  "aa@qq.com",
  "b@qq.com",
  "c@qq.com"
  ]
  }
  >var x = db.tmps.findOne()
  (test)>x.age = 23
  23
  >db.tmps.save(x)
  WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
  >db.tmps.findOne()
  {
  "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),
  "name" : "joe",
  "age" : 23,
  "emails" : [
  "bb@qq.com",
  "cc@qq.com",
  "dd@qq.com",
  "aa@qq.com",
  "b@qq.com",
  "c@qq.com"
  ]
  }
  更新多个文档:
  默认情况,更新只对匹配条件的第一个文档执行操作。要更新所有匹配,可以将update的第四个参数设置为true。
  >db.tmps.find()
  { "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"), "name" : "joe", "age" : 23 }
  { "_id" : ObjectId("54f6aa46d9c146390ce21c5f"), "name" : "peter", "age" : 23 }
  { "_id" : ObjectId("54f6aa4cd9c146390ce21c60"), "name" : "carlo", "age" : 23 }
  >db.tmps.update({"age":23}, {"$set":{"age":24}},false,true)     //简写方式
  >db.tmps.update({"age":23}, {"$set":{"age":24}},{upsert:false,multi:true})
  >db.tmps.find()
  { "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"), "name" : "joe", "age" : 24 }
  { "_id" : ObjectId("54f6aa46d9c146390ce21c5f"), "name" : "peter", "age" : 24 }
  { "_id" : ObjectId("54f6aa4cd9c146390ce21c60"), "name" : "carlo", "age" : 24 }
  写入安全机制(write concern)
  是一种客户端设置,用于控制写入的安全级别。
  PS:内容整理于《Mongodb权威指南》


运维网声明 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-626746-1-1.html 上篇帖子: mongoDB Connection String URI Format¶ 下篇帖子: Solr] (源) Solr与MongoDB集成,实时增量索引
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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