MyException - 我的异常网
当前位置:我的异常网» Go » MongoDB-基础-02-数据操作

MongoDB-基础-02-数据操作

www.MyException.Cn  网友分享于:2015-03-15  浏览:0次
MongoDB-基础-02--数据操作

 

出处:http://www.cnblogs.com/stephen-liu74/archive/2012/08/06/2553737.html

 

1.  批量插入:

     以数组的方式一次插入多个文档可以在单次TCP请求中完成,避免了多次请求中的额外开销。就数据传输量而言,批量插入的数据中仅包含一份消息头,而多次单条插入则会在每次插入数据时封装消息头数据。对于数据导入而言,我们可以使用mongoimport完成。

 

2.  数据库清除:

    > db.users.remove() 

    以上命令将会清除users集合中的所有数据,但是不会删除集合本身以及关联的索引。数据删除操作是不可恢复的,一旦删除就物理的删除了。对于全集合清除这种case,一个更为有效的方式是直接删除集合对象本身以及他关联的所有索引,之后再依次重建,如:

    > db.one_collection.drop()

 

3.  数据更新:  

    如果在执行数据更新时,有多条文档匹配更新条件,为了避免更新后的_id出现重复性冲突,MongoDB将仅更新第一条查询结果,如:

    > post1 = { "name": "stephen", "age" : "35"}

    { "name" : "stephen", "age" : "35" }

    > post2 = { "name": "stephen", "age" :  36}

    { "name" : "stephen", "age" : 36 }

    > db.blog.insert(post1)

    > db.blog.insert(post2)

    > post3 = { "name" : "stephen", "age": 37}

    { "name" : "stephen", "age" : 37 }

    > db.blog.update({"name":"stephen"},post3)

    > db.blog.find()

    { "_id" : ObjectId("4fcd7e2e20668578cc1097d8"), "name" : "stephen", "age" : 36 }

    { "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 37 }

 

 

 

4.  修改器:

    使用修改器进行数据更新是原子的,也是高效的,不同于全部文档更新的是被更新文档的_id不会变化,而文档完全更新则会修改文档的_id,以及相关的索引。

    > db.blog.find()

    { "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 41 }

    { "_id" : ObjectId("4fcd81bb20668578cc1097d9"), "name" : "stephen", "age" : 38 }

    --$inc修改符将匹配条件的文档的age键原子加一,缺省情况下只是更新第一条符合条件的文档。

    > db.blog.update({"name":"stephen"},{"$inc":{"age":1}})  

    > db.blog.find()

    { "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 42 }

    { "_id" : ObjectId("4fcd81bb20668578cc1097d9"), "name" : "stephen", "age" : 38 }

    --可以通过update函数的最后一个参数来指定更新所有符合条件的文档,如:

    > db.blog.update({"name":"stephen"},{"$inc":{"age":1}},true,true)

    > db.blog.find()

    { "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 43 }

    { "_id" : ObjectId("4fcd81bb20668578cc1097d9"), "name" : "stephen", "age" : 39 } 

 

    --$set修改符直接修改匹配文档的内容,如果修改的键存在则直接修改,否则新增。

    > db.blog.update({"name":"stephen"},{"$set":{"genda":"male"}})

    > db.blog.find()

    { "_id" : ObjectId("4fcd88b720668578cc1097da"), "age" : "35", "genda" : "male", "name" : "stephen" }

    --$unset修改符合$set的功能是完全相反的,如:

    > db.blog.update({"name":"stephen"},{"$unset":{"genda":"male"}})

    > db.blog.find()

    { "_id" : ObjectId("4fcd88b720668578cc1097da"), "age" : "35", "name" : "stephen" }

    --可以通过$set修改符修改嵌套子文档。

    > db.blog.find()

    { "_id" : ObjectId("4fcd8e0220668578cc1097db"), "title" : "A Blog Post", "author" : { "name" : "joe", "email" : "joe@ee.com" } }

    > db.blog.update({"title":"A Blog Post"},{"$set":{"author.name":"joe schmoe"}})

    > db.blog.find()

    { "_id" : ObjectId("4fcd8e0220668578cc1097db"), "author" : { "email" : "joe@ee.com", "name" : "joe schmoe" }, "title" : "A Blog Post" }

 

 

 

5.  数组修改器:

    > db.blog.insert({"title":"one blog"})

    > db.blog.find()

    { "_id" : ObjectId("4fcd909520668578cc1097dc"), "title" : "one blog" }

    --如果其操作的键不存在,则创建新的键值,其值的类型为数组类型。

    > log.update({"title":"one blog"}, {"$push": {"comments":{"content":"hello"}}})

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fcd909520668578cc1097dc"),

         "comments" : [

                 {

                         "content" : "hello"

                 }

         ],

         "title" : "one blog"

    }

    --如果$push操作的键值已经存在,且其值为数组类型,该修改符将为该数组添加新的数组元素。

    > db.blog.update({"title":"one blog"}, {"$push": {"comments":{"content":"word"}}

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fcd909520668578cc1097dc"),

         "comments" : [

                 {

                         "content" : "hello"

                 },

                 {

                         "content" : "word"

                 }

         ],

         "title" : "one blog"

    }

 

    > post = {"username":"joe", "emails":["joe@example.com","joe@gmail.com","joe@yahoo.com"]}

    {

         "username" : "joe",

         "emails" : [

                 "joe@example.com",

                 "joe@gmail.com",

                 "joe@yahoo.com"

         ]

    }

    > db.blog.insert(post)

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2e468b2ac404941134bed"),

         "username" : "joe",

         "emails" : [

                 "joe@example.com",

                 "joe@gmail.com",

                 "joe@yahoo.com"

         ]

    }

    --$addToSet适用于数组,如果数组中该元素已经存在,该命令就不做任何操作后返回,否则将新元素插入数组。

    > db.blog.update({"username":"joe"}, {"$addToSet": {"emails":"joe@gmail.com"}})

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2e468b2ac404941134bed"),

         "username" : "joe",

         "emails" : [

                 "joe@example.com",

                 "joe@gmail.com",

                 "joe@yahoo.com"

         ]

    }

    > db.blog.update({"username":"joe"}, {"$addToSet": {"emails":"joe@hotmail.com"}

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2e468b2ac404941134bed"),

         "emails" : [

                 "joe@example.com",

                 "joe@gmail.com",

                 "joe@yahoo.com",

                 "joe@hotmail.com"

         ],

         "username" : "joe"

    }

    --$addToSet和$each的组合可以将数组插入到另外一个数组中。

    > db.blog.update({"username":"joe"},{"$addToSet": {"emails":{"$each":["joe@php.net","joe@example.com"]}}})

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2e468b2ac404941134bed"),

         "emails" : [

                 "joe@example.com",

                 "joe@gmail.com",

                 "joe@yahoo.com",

                 "joe@hotmail.com",

                 "joe@php.net"

         ],

         "username" : "joe"

    }

    --$pop从数组中删除一个元素,如参数为1,表示从数组的尾部删除一个元素,如果是-1,则从头部删除。

    > db.blog.update({"username":"joe"}, {"$pop":{"emails":1}})

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2e468b2ac404941134bed"),

         "emails" : [

                 "joe@example.com",

                 "joe@gmail.com",

                 "joe@yahoo.com",

                 "joe@hotmail.com"

         ],

         "username" : "joe"

    }

    > db.blog.update({"username":"joe"}, {"$pop":{"emails":-1}})

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2e468b2ac404941134bed"),

         "emails" : [

                 "joe@gmail.com",

                 "joe@yahoo.com",

                 "joe@hotmail.com"

         ],

         "username" : "joe"

    } 

    --$pull修改符则是从数据中删除指定的元素

    > db.blog.update({"username":"joe"}, {"$pull":{"emails":"joe@yahoo.com"}})

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2e468b2ac404941134bed"),

         "emails" : [

                 "joe@gmail.com",

                 "joe@hotmail.com"

         ],

         "username" : "joe"

    }

    --使数组中出现重复的元素,便于后面修改符的功能演示。

    > db.blog.update({"username":"joe"}, {"$push": {"emails":"joe@gmail.com"}})

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2e468b2ac404941134bed"),

         "emails" : [

                 "joe@gmail.com",

                 "joe@hotmail.com",

                 "joe@gmail.com"

         ],

         "username" : "joe"

    }

    --在数组中,第一个元素的下标是0,然后依次增长。下面的示例是将数组中下标为1

    --(第二个元素)的元素值修改为新值。

    > db.blog.update({"username":"joe"}, {"$set":{"emails.1":"joe@example.com"}})

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2e468b2ac404941134bed"),

         "emails" : [

                 "joe@gmail.com",

                 "joe@example.com",

                 "joe@gmail.com"

         ],

         "username" : "joe"

    }

    --有的时候,特别是在修改查询结果的时候,我们无法获知结果文档数组下标,MongoDB

    --提供了$定位符表示查询结果的下标。但是该他只更新第一个匹配元素。

    > db.blog.update({"emails":"joe@gmail.com"},{"$set":{"emails.$":"joe@hotmail.com"}})

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2e468b2ac404941134bed"),

         "emails" : [

                 "joe@hotmail.com",

                 "joe@example.com",

                 "joe@gmail.com"

         ],

         "username" : "joe"

   }

 

6.  upsert:

    upsert是一种特殊的更新。要是没有文档符合更新条件,就会以这个条件和更新文档为基础创建一个新的文档。如果找到了匹配的文档,则正常更新。

    > db.blog.remove()

    > db.blog.update({"username":"joe"},{"username":"joe","age":30},true) 

    > db.blog.findOne()

    {

         "_id" : ObjectId("4fd2faac576cd9c101ac0f3d"),

         "username" : "joe",

         "age" : 30

    }

    下面的示例可以在新增的同时,修改新增后的值。 

    > db.blog.remove()

    > db.blog.update({"count":25},{"$inc":{"count":3}},true)

    > db.blog.find()

    { "_id" : ObjectId("4fd2fd59576cd9c101ac0f3e"), "count" : 28 }

    save是一个shell函数,可以在文档不存在时插入,存在时更新。upsert也可以完成同样的工作,但是不如save命令方便。

    > var x = db.blog.findOne()

    > x.count = 40

    40

    > db.blog.save(x)

    > db.blog.findOne()

    { "_id" : ObjectId("4fd2fde4576cd9c101ac0f3f"), "count" : 40 }

 

7.  返回已更新文档:

    可以通过getLastError命令获取更新多个文档时被更新的文档数量。

    > db.blog.remove()

    > db.blog.insert({"name":"stephen"})

    > db.blog.insert({"name":"stephen3"})

    > db.blog.insert({"name":"stephen4"})

    > db.blog.update({},{"$set":{"name":"liu"}},false,true)

    --n:3表示修改的数量为3。

    > db.runCommand({getLastError:1})

    {

        "updatedExisting" : true,

        "n" : 3,

        "connectionId" : 1,

        "err" : null,

        "ok" : 1

    }

    findAndModify可以原子性的修改查询结果,也可以原子性的删除查询结果。

    > db.blog.insert({"name":"stephen"})

    > db.blog.insert({"name":"stephen2"})

    > db.blog.find()

    { "_id" : ObjectId("4fd30cd117f6dccb7c058244"), "name" : "stephen" }

    { "_id" : ObjectId("4fd30cd417f6dccb7c058245"), "name" : "stephen2" }         

    > db.runCommand({"findAndModify":"blog", "query":{"name":"stephen2"},"update":{"$set":{"name":"stephen3"}}})

    > db.blog.find()

    { "_id" : ObjectId("4fd30cd117f6dccb7c058244"), "name" : "stephen" }

    { "_id" : ObjectId("4fd30cd417f6dccb7c058245"), "name" : "stephen3" } 

    > runCommand({"findAndModify":"blog", "query":{"name":"stephen3"},"remove":true})

    > db.blog.find()

    { "_id" : ObjectId("4fd30cd117f6dccb7c058244"), "name" : "stephen" }

    findAndModify命令中每个键对应的值如下:

    findAndModify: 字符串类型的集合名称。

    query:查询文档,用来检索文档的条件。

    sort: 排序结果的条件。

    update:修改文档,对所找到的文档执行的更新。

    remove:布尔类型,表示是否删除文档。

    new:布尔类型,表示返回的是更新前的文档还是更新后的文档。缺省是更新前文档。

    update和remove必须有一个存在,也只能有一个存在。如果没有匹配的文档,该命令会返回一个错误。这个命令有些限制,即一次只能处理一个文档,也不能执行upsert操作,只能更新已有文档。

文章评论

“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
那些争议最大的编程观点
那些争议最大的编程观点
代码女神横空出世
代码女神横空出世
10个调试和排错的小建议
10个调试和排错的小建议
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
老程序员的下场
老程序员的下场
旅行,写作,编程
旅行,写作,编程
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
一个程序员的时间管理
一个程序员的时间管理
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
Java程序员必看电影
Java程序员必看电影
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
鲜为人知的编程真相
鲜为人知的编程真相
中美印日四国程序员比较
中美印日四国程序员比较
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
程序员和编码员之间的区别
程序员和编码员之间的区别
我的丈夫是个程序员
我的丈夫是个程序员
漫画:程序员的工作
漫画:程序员的工作
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
如何成为一名黑客
如何成为一名黑客
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员都该阅读的书
程序员都该阅读的书
每天工作4小时的程序员
每天工作4小时的程序员
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
总结2014中国互联网十大段子
总结2014中国互联网十大段子
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
程序员的鄙视链
程序员的鄙视链
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
程序员必看的十大电影
程序员必看的十大电影
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
程序员应该关注的一些事儿
程序员应该关注的一些事儿
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有