每篇半小时1天入门MongoDB——3.MongoDB可视化及shell详解

本篇主要介绍MongoDB可视化操作以及shell使用及命令,备份恢复、数据导入导出。

MongoVUE安装和简单使用

使用mongo.exe 管理数据库虽然可行,功能也挺强大,但每次都要敲命令,即繁琐枯燥而且效率低下。MongoDb在Windows下的可视化操作的管理工具非常多,笔者从中找了几款使用了一翻,最后挑了一款MongoVUE来最简单介绍,因为笔者觉得MongoVUE界面看上去舒服些。

下载地址:http://www.mongovue.com/downloads/

注意:官方提供的是收费版,试用期15天。但是天朝的东西,你懂的,破解很容易。

运行效果如下图所示。

添加数据库连接之前,要先运行Mongo服务,然后添加Mongo数据库连接,如下图所示。

Document数据插入

> show collections
persons
system.indexes
> db.persons.find()
{ "_id" : ObjectId("593959250ab68d9cc7011a93"), "name" : "玉杰" }
{ "_id" : ObjectId("59395c350ab68d9cc7011a94"), "name" : "楚留香" }

1.插入文档

db.[documentName].insert({})

2.批量插入文档

  • shell这样执行是错误的:db.[documentName].insert([{},{},...])
  • shell不支持批量插入
  • 想完成批量插入可以使用Mongo的应用驱动或者是shell的for循环
> for(var i=0;i<10;i++){
... db.persons.insert({name:‘test‘+i})}
WriteResult({ "nInserted" : 1 })
> db.persons.find()
{ "_id" : ObjectId("593959250ab68d9cc7011a93"), "name" : "玉杰" }
{ "_id" : ObjectId("59395c350ab68d9cc7011a94"), "name" : "楚留香" }
{ "_id" : ObjectId("593b489e29b0f45384dfaafa"), "name" : "test0" }
{ "_id" : ObjectId("593b489e29b0f45384dfaafb"), "name" : "test1" }
{ "_id" : ObjectId("593b489e29b0f45384dfaafc"), "name" : "test2" }
{ "_id" : ObjectId("593b489e29b0f45384dfaafd"), "name" : "test3" }
{ "_id" : ObjectId("593b489e29b0f45384dfaafe"), "name" : "test4" }
{ "_id" : ObjectId("593b489e29b0f45384dfaaff"), "name" : "test5" }
{ "_id" : ObjectId("593b489e29b0f45384dfab00"), "name" : "test6" }
{ "_id" : ObjectId("593b489e29b0f45384dfab01"), "name" : "test7" }
{ "_id" : ObjectId("593b489e29b0f45384dfab02"), "name" : "test8" }
{ "_id" : ObjectId("593b489e29b0f45384dfab03"), "name" : "test9" }
>

3.Save操作

save操作和insert操作的区别在于当遇到_id相同的情况下,save完成保存操作,而insert则会报错

我们先来看下insert操作,先插入一条01的记录,然后再插入一条_id为01的记录会报错,因为_id重复了。

> db.persons.insert({_id:"01",name:1})
WriteResult({ "nInserted" : 1 })
> db.persons.insert({_id:"01",name:2})
WriteResult({
        "nInserted" : 0,
        "writeError" : {
                "code" : 11000,
                "errmsg" : "E11000 duplicate key error index: myTest.persons.$_id_ dup key: { : \"01\" }"
        }
})
>

再来看下save操作,直接将_id为01的记录更新了,name由1更新为了2

> db.persons.save({_id:"01",name:2})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : ObjectId("593959250ab68d9cc7011a93"), "name" : "玉杰" }
{ "_id" : ObjectId("59395c350ab68d9cc7011a94"), "name" : "楚留香" }
{ "_id" : ObjectId("593b489e29b0f45384dfaafa"), "name" : "test0" }
{ "_id" : ObjectId("593b489e29b0f45384dfaafb"), "name" : "test1" }
{ "_id" : ObjectId("593b489e29b0f45384dfaafc"), "name" : "test2" }
{ "_id" : ObjectId("593b489e29b0f45384dfaafd"), "name" : "test3" }
{ "_id" : ObjectId("593b489e29b0f45384dfaafe"), "name" : "test4" }
{ "_id" : ObjectId("593b489e29b0f45384dfaaff"), "name" : "test5" }
{ "_id" : ObjectId("593b489e29b0f45384dfab00"), "name" : "test6" }
{ "_id" : ObjectId("593b489e29b0f45384dfab01"), "name" : "test7" }
{ "_id" : ObjectId("593b489e29b0f45384dfab02"), "name" : "test8" }
{ "_id" : ObjectId("593b489e29b0f45384dfab03"), "name" : "test9" }
{ "_id" : "01", "name" : 2 }
>

Document数据删除

1.删除列表中所有数据

db.[documentName].remove()
集合的本身和索引不会被删除。删除文档是永久性的,不能撤销,也不能恢复的。因此,在执行remove()函数前先用find()命令来查看下是否正确,是个比较好的习惯啦。

> db.persons.remove({})
WriteResult({ "nRemoved" : 13 })
> db.persons.find()
> show collections
persons
system.indexes
> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.persons" }
>

2.根据条件删除

删除集合persons中name等于yujie的记录

remove()函数可以接受一个查询文档作为可选参数来有选择性的删除符合条件的文档

先来插入几条测试记录

> db.persons.insert({name:"yujie"})
WriteResult({ "nInserted" : 1 })
> db.persons.insert({name:"zouqj"})
WriteResult({ "nInserted" : 1 })
> db.persons.find()
{ "_id" : ObjectId("593b4c5329b0f45384dfab04"), "name" : "yujie" }
{ "_id" : ObjectId("593b4c5e29b0f45384dfab05"), "name" : "zouqj" }
>

再来删除name等于yujie的记录

> db.persons.remove({name:"yujie"})
WriteResult({ "nRemoved" : 1 })
> db.persons.find()
{ "_id" : ObjectId("593b4c5e29b0f45384dfab05"), "name" : "zouqj" }
>

3.小技巧

如果你想清除一个数据量十分庞大的集合,直接删除该集合并且重新建立索引的办法比直接remove的效率要高很多。

Document数据更新

db.[documentName].update(参数1,参数2,[参数3],[参数4])

  • 参数1:查询的条件
  • 参数2:更新的字段
  • 参数3:如果不存在则插入
  • 参数4:是否允许修改多条记录

1.强硬的文档替换式更新操作

db.[documentName].update({查询器},{修改器})

> db.persons.insert({name:"yujie",age:29})
WriteResult({ "nInserted" : 1 })
> db.persons.find()
{ "_id" : ObjectId("593b4c5e29b0f45384dfab05"), "name" : "zouqj" }
{ "_id" : ObjectId("593b540529b0f45384dfab06"), "name" : "yujie", "age" : 29 }
> db.persons.update({name:"yujie"},{age:30})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : ObjectId("593b4c5e29b0f45384dfab05"), "name" : "zouqj" }
{ "_id" : ObjectId("593b540529b0f45384dfab06"), "age" : 30 }
>

原本我是想把name等于yujie的记录,将其age更新为30,可是会发现虽然age更新为30了,但是也把"name" : "yujie"直接给删除了。因为:强硬的更新会用新的文档替代老的文档,其实就相当于先删除再插入的操作。

2.主键冲突的时候会报错并且停止更新操作

因为是强硬替换,当替换的文档和已有的文档ID冲突的时候,系统会报错。

先来插入几条测试记录

> db.persons.insert({_id:1,name:"test1"})
WriteResult({ "nInserted" : 1 })
> db.persons.insert({_id:2,name:"test2"})
WriteResult({ "nInserted" : 1 })
> db.persons.find()
{ "_id" : ObjectId("593b4c5e29b0f45384dfab05"), "name" : "zouqj" }
{ "_id" : ObjectId("593b540529b0f45384dfab06"), "age" : 30 }
{ "_id" : 1, "name" : "test1" }
{ "_id" : 2, "name" : "test2" }
>

然后我们再来强硬更新,会发现报错了。

> db.personso.update({_id:1},{_id:2,name:"test2"})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
> db.persons.update({_id:1},{_id:2,name:"test2"})
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 16837,
                "errmsg" : "The _id field cannot be changed from {_id: 1.0} to {_id: 2.0}."
        }
})
>

3.insertOrUpdate操作

db.[documentName].update({查询器},{修改器},true)

目的:查询器查出来数据就执行更新操作,查不出来就替换操作。

> db.persons.update({_id:3},{_id:3,name:"test3"},true)
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 3 })
> db.persons.find()
{ "_id" : ObjectId("593b4c5e29b0f45384dfab05"), "name" : "zouqj" }
{ "_id" : ObjectId("593b540529b0f45384dfab06"), "age" : 30 }
{ "_id" : 1, "name" : "test1" }
{ "_id" : 2, "name" : "test2" }
{ "_id" : 3, "name" : "test3" }
>

4.批量更新操作

默认情况下,当查询器查询出多条数据的时候默认就修改第一条数据,如何实现批量修改:
db.[documentName].update({查询器},{修改器},false,true)

5.修改器【通过修改器来完成局部更新操作】

修改器名称 语法 说明 示例
$set {$set:{field:value}} 用于指定一个键值对,存在就修改,不存在就添加 {$set:{name:”Leon”}}
$inc {$inc:{field:value}} 只适用于数字类型的字段值修改,对指定字段进行增减指定数值 {$inc:{age:1}}
$unset {$unset:{field:1}} 删除指定的字段 {$unset:{age:1}}
$push {$push:{field:value}} 指定的字段必须是数组,否则中断,指定的字段不存在则创建 {$push:{family:”brother”}}
$pushAll {$pushAll:{field:array}} 要求同push,一次添加多个元素到数组 {$pushAll:{family:[“father”,”mother”,”brother”]}}
$addToSet {$addToSet:{field:value}} 将值插入匹配元素指定的数组中,如果该值已存在则不添加 {$addToSet:{family:”sister”}
$pop {$pop:{field:value}} 从指定字段中数组中删除一个值,value接受正数(最后一个)和负数(第一个),一般使用1和-1 {$pop:{family:1}}
$pull $pull:{field:value} 从指定字段中的数组中删除指定的一个值 {$pull:{family:”father”}}
$pullAll {$pullAll:{field:array}} 从指定字段中的数组中删除指定的所有值 {$pullAll:{family:[“father”,”mother”]}}
$ 这是一个定位器非修改器,用于定位数组中的指定键  

6.$addToSet与$each结合完成批量数组更新

db.persons.update({_id:1},{$addToSet:{books:{$each:{"js","db"]}}})
$each会循环后面的数组把每一个数值进行$addToSet操作

7.存在分配与查询效率

当document被创建的时候DB为其分配内存和预留内存,当修改操作不超过预留内存的时候,则速度
非常快,反之,若超过了就要分配新的内存,从而消耗时间。

时间: 2024-08-06 07:57:05

每篇半小时1天入门MongoDB——3.MongoDB可视化及shell详解的相关文章

每篇半小时1天入门MongoDB——2.MongoDB环境变量配置和Shell操作

上一篇:每篇半小时1天入门MongoDB——1.MongoDB介绍和安装 配置环境变量 Win10系统为例 右键单击“此电脑”——属性——高级系统设置——高级——环境变量,添加C:\Program Files\MongoDB\Server\3.0\bin;.注意:要以;隔开各种变量. 这样的话就可以直接在CMD命令窗口中输入mongo 表示环境变量设置成功,并已经连接到默认数据库test中. 我们可以输入mongod --help来查看相关的帮助信息 C:\Users\zouqi>mongod

每篇半小时1天入门MongoDB——4.MongoDB索引介绍及数据库命令操作

准备工作 继续连接到mongo C:\Users\zouqi>mongo MongoDB shell version: 3.0.7 connecting to: test 查看数据库和集合 > show dbs demo 0.078GB local 0.078GB myDatabase 0.078GB myTest 0.078GB > use myTest switched to db myTest > show collections persons system.indexes

Android基础入门教程——8.3.16 Canvas API详解(Part 1)

Android基础入门教程--8.3.16 Canvas API详解(Part 1) 标签(空格分隔): Android基础入门教程 本节引言: 前面我们花了13小节详细地讲解了Android中Paint类大部分常用的API,本节开始我们来讲解 Canvas(画板)的一些常用API,我们在Android基础入门教程--8.3.1 三个绘图工具类详解 中已经列出了我们可供调用的一些方法,我们分下类: drawXxx方法族:以一定的坐标值在当前画图区域画图,另外图层会叠加, 即后面绘画的图层会覆盖前

Android基础入门教程——2.5.3 AlertDialog(对话框)详解

Android基础入门教程--2.5.3 AlertDialog(对话框)详解 标签(空格分隔): Android基础入门教程 本节引言: 本节继续给大家带来是显示提示信息的第三个控件AlertDialog(对话框),同时它也是其他 Dialog的的父类!比如ProgressDialog,TimePickerDialog等,而AlertDialog的父类是:Dialog! 另外,不像前面学习的Toast和Notification,AlertDialog并不能直接new出来,如果你打开 Alert

Android基础入门教程——8.3.18 Canvas API详解(Part 3)Matrix和drawBitmapMash

Android基础入门教程--8.3.18 Canvas API详解(Part 3)Matrix和drawBitmapMash 标签(空格分隔): Android基础入门教程 本节引言: 在Canvas的API文档中,我们看到这样一个方法:drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) 这个Matrix可是有大文章的,前面我们在学Paint的API中的ColorFilter中曾讲过ColorMatrix 颜色矩阵,一个4 * 5 的矩阵

Android基础入门教程——2.3.2 EditText(输入框)详解

Android基础入门教程--2.3.2 EditText(输入框)详解 标签(空格分隔): Android基础入门教程 本节引言: 上一节中我们学习了第一个 UI控件TextView(文本框),文中给出了很多实际开发中可能遇到的一些需求 的解决方法,应该会为你的开发带来便利,在本节中,我们来学习第二个很常用的控件EditText(输入框): 和TextView非常类似,最大的区别是:EditText可以接受用户输入!和前面一样,我们不一个个讲属性, 只讲实际应用,要扣属性可以自己查看API文档

VB.NET 章鱼哥出品--入门基础Button控件的使用详解(一)

全网最全的Button控件详解!!!Button 按钮是VB.NET 中最基础,也是最常用的控件,不管你是初学者还是大牛.每个程序中必然少不了Button按钮.但是Button控件有很多用法很多大牛却不见得知道.用的最多的无非就是在点击事件中处理程序,今天我将使用2到3篇文章的篇幅来详细讲解Button按钮的用法.      '作者:章鱼哥,QQ:3107073263 群:309816713            '如有疑问或好的建议请联系我,大家一起进步     1,属性(以最常用的开始) (

mongodb主从以及auth主从 配置详解

1.主服务器配置 #auth = true dbpath = /data/mongodb/db logpath = /data/mongodb/log/mongodb.log port = 27017 fork = true  #以守护程序的方式启用,即在后台运行 nohttpinterface = true logappend=true master=true 2.从服务器配置 #auth = true dbpath = /data/mongodb/db logpath = /data/mon

MongoDB复制集及数据分片详解

前言 MongoDB是一个由C++语言编写的基于分布式文件存储的数据库,是当前NoSQL数据库中比较热门的一种,旨在为Web应用提供可扩展的高性能数据存储解决方案.本文介绍MongoDB复制集及数据分片. MongoDB 简介 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.支持的数据结构非常松散,因此可以存储比较复杂的数据类型.最大的特点是其支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询