最近在自学MongoDB,在此记录一下,当做学习笔记了(不断更新中)!!

一、背景

  MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。它是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

  其放弃关系模型的原因就是为了获得更加方便的扩展、稳定容错等特性。面向文档的基本思路就是:将关系模型中的“行”的概念换成“文档(document)”模型。面向文档的模型可以将文档和数组内嵌到文档中。因此,实际中可以用一条数据表示非常复杂的结构。MongoDB没有预定义模式:文档的键(key)和值(value)不再是固定的类型和大小,而且根据需求要添加或者删除字段变得更容易了。

  实际应用中,随着数据量的增大,数据库都要进行扩展。扩展有纵向扩展和横向扩展。纵向扩展是使用计算能力更强的机器,也是最省力的方法,但是很容易达到物理极限,无论花多少钱也买不到最新的机器了。横向扩展就是通过分区将数据分散到更多的机器上。MongoDB的设计采用横向扩展。面向文档的数据模型使它很容易地在多台服务器之间进行数据分割。还可以自动处理跨集群的数据和负载,自动重新分配文档,以及将用户请求路由到正确的机器上。开发者根本不用考虑数据库层次的扩展问题,需要扩展数据库时,在集群中添加机器即可,MongoDB会自动处理后续的事情。


二、MongoDB的优势与劣势

优势

    1. 快速!基于内存,将热数据存放在物理内存中(不仅仅只是索引和少部分数据),从而提高了整体速度和效率。
    2. 高扩展性!MongoDB的高可用和集群架构拥有十分高的扩展性。
    3. 自身的FailOver机制!在副本集中,当主库遇到问题,无法继续提供服务的时候,副本集将选举一个新的主库继续提供服务。
    4. JSon格式的数据!MongoDB的Bson和JSon格式的数据十分适合文档格式的存储与查询。

劣势

    1. 应用经验少!由于NoSQL兴起时间短,应用经验相比关系型数据库较少。
    2. 由于以往用到的都是关系型数据库,可能会造成使用者一开始的不适应。
    3. 无事务机制!MongoDB本身没有自带事务机制,若需要在MongoDB中实现事务机制,需通过一个额外的表,从逻辑上自行实现事务。

三、MongoDB数据类型

四、常用命令

1)  db:查看当前的数据库;

2)  show dbs:显示所有数据库列表;

3)  db.stats():查看数据库状态;

4)  use:切换到某个数据库;

5)  db.dropDatabase():删除数据库(需要先切换到对应的数据库);(用的时候自己创建)

6)  db.createCollection(name, options):创建集合;(用的时候自己创建)

7)  db.${collection}.drop():删除集合;

8)  db.${collection}.insert():插入文档;

9)  db.${collection}.save():插入文档;

10)   db.${collection}.findOne():查看一篇文档;

11)   db.${collection}.find().pretty():以更加友好的方式查看已插入文档;

12)   db.collection.update():更新文档;

13)   db.collection.remove():删除文档;但是并不会释放存储空间,需执行db.repairDatabase() 来回收磁盘空间。推荐deleteOne(),deleteMany();

14)   db.${collection}.deleteMany({}):删除全部文档

15)   db.${collection}.deleteOne({}):删除符合条件的一个文档

16)   db.${collection}.find().limit(${num}):读取指定数量的数据记录;

17)   db.${collection}.find().limit(${num1}).skip(${num2}):跳过指定数量的数据

18)   db.${collection}.find().sort({${key}:1/-1}):排序,1升序,-1降序

19)   db.${collection}.createIndex():创建索引

20)   db. ${collection}.help();  #查询对相应表的一些操作

21)   db.mycoll.find().help();  #查询的方法,排序,最大最小等...

五、插入

mongoDB中插入数据有insert()与save()两个命令,二者的联系是:

1)  对于数据库中没有改字段,两者没有区别;

2)  对于数据库中有该字段,insert会报错,save会执行更新操作

3)  若新增的数据中存在主键 ,insert() 会提示错误,而save() 则更改原来的内容为新内容。

save()

db.student.save({_id:1,classid:1,age:18,name:"little1",love:["football","swing","cmpgame"]});
db.student.save({_id:2,classid:2,age:19,name:"little2",love:["play"]});
db.student.save({_id:3,classid:2,age:20,name:"little3"});
db.student.save({_id:4,classid:1,age:21,name:"little4"});
db.student.save({_id:5,classid:1,age:22,name:"little5",opt:"woshisheia"});
db.student.save({_id:6,classid:2,age:23,name:"23little4"});

insert():int类型赋值不要加引号,字符串赋值要加引号,单引号和双引号都可以,推荐使用单引号,因为双引号在一些编辑器中转义会有一些问题

1)插入普通数据命令: db.goods.insert({name:'xiaomi',price:2000,number:'50'})

2)插入具有对象数据命令:db.goods.insert({name:'xiaomi',price:2000,number:'50',area:{province:'jiangsu',city:'nanjing'}})

3)插入数组数据命令: db.goods.insert({name:'xiaomi',price:2000,number:'50',area:{province:'jiangsu',city:'nanjing'},color:['black','red','greed']})

4)批量插入数据:for (i=0;i<1000;i++) db.tables1.insert({name:"Alex"+i});

六、查询

1)find({${where条件},${0属性不显示 /1属性显示}}):查询,如果where条件没有,那就用{}表示,不能省略。而显示与否的{}可以省略的。

db.student.find();

//查询 name为little1的学生,并且只显示 age,name两个字段
db.student.find({name:"little1"},{name:1,age:1})       等价于 select name,age from student where name = "little1"

//and:查询 name为little1,age为18的学生,并且只显示 age,name,love三个字段
db.student.find({name:"little1",age:18},{name:1,age:1,love:1})  等价于 select name,age,love from student where name = "little1" and age = 18

//$or:查询 name为little3或age为19的学生
db.student.find({'$or':[{name:'little3'},{age:19}]})  等价于 select * from student where name = "little3" or age = 19

db.student.find({'$or':[{name:'little3'},{age:19}]},{name,1})

2)findOne({${where条件},${0属性不显示 /1属性显示}}):查询,只返回第一个

db.student.findOne().pretty();    这里的pretty()是将结果格式化,find() 与 findOne() 后面都可以使用

3)skip(num): 参数num表示跳过的记录条数,默认值为0。 limit(num):  参数num表示要获取文档的条数,如果没有指定参数则显示集合中的所有文档。skip() 与 limit() 不分先后顺序 ,从第二条查寻,查出三条

db.student.find().skip(1).limit(3);

4)比较运算符号

//查询出19<age<=21的数据
db.student.find({age:{$gt:19,$lte:21}});

//查询age>20的数据
db.student.find({age:{$gt:20}});

db.student.find({$where:"this.age>20"});

db.student.find("this.age>20");

var f = function(){return this.age>20};
db.student.find(f);

5)$mod:查询出age为奇数的数据(对2求余为1即为奇数)(这里请注意[2,1]的位置不能错)。

db.student.find({age:{$mod:[2,1]}});    也可写作:

6)$exists:查询出存在opt字段的数据,  存在true,不存在false

db.student.find({opt:{$exists:true}});    db.student.find({opt:{$exists:false}});

7)查询出name不为little2的数据

db.student.find({name:{$ne:"little2"}});

8)$in:查询出age为16,18,19的数据

db.student.find({age:{$in:[16,18,19]}});

    
9)$nin:查询出age不为16,18,19的数据

db.student.find({age:{$nin:[16,18,19]}});

10)$size:查询出love有三个的数据

db.student.find({love:{$size:3}});

11)查询出name不是以litt开头的数据

db.student.find({name:{$not:/^litt.*/}});

12)sort:1升序,   -1降序

按age升序:db.student.find().sort({age:1});   按age降序:db.student.find().sort({age:-1});


13)count:查询数据条数。
db.集合名称.find({条件}).count()  或者  db.集合名称.count({条件})

db.student.find().count();  也可以写作db.student.count()

14)like:模糊查询

db.student.find({name:/little/});    相当于 select * from student where name like "%little%";

db.student.find({name:/^little/});    相当于 select * from users where name like "little%";

15)distinct:去重。格式:db.集合名称.distinct('去重字段',{条件})

db.student.distinct('name');

  //查找年龄大于18的学生,来自哪些省份

db.stu.distinct('hometown',{age:{$gt:18}})


16)type:属性类型判断    常见的Double 是1,String是2,Boolean是8,Date是9,Null是10,32位int是16,Timestamp是17,64位int是18

db.sutdent.find({"title" : {$type : 2}})         db.student.find({"title" : {$type : 'string'}})

17)null:查询age为null的数据

db.student.find({age:null})

18)聚合(aggregate),主要用于计算数据,类似sql中的sum()、avg()

  待补

七、更新

update() 方法用于更新已存在的文档。语法格式如下:

db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)

参数说明:

    • query : update的查询条件,类似sql update查询内where后面的。
    • update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
    • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
    • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
    • writeConcern :可选,抛出异常的级别。

例:

db.person.insert([{"name":"chen","age":15},{"name":"li","age":20},{"name":"zhang","age":20}]);

$ set修改符

用于修改键的值,如果键不存在就增加键

//将age=10的数据改成15,默认如果age=10的有多条记录只更新第一条

db.person.update({"name":"li"},{$set:{"age":10}})

//更新多个满足条件的值,同时如果更新的值不存在就插入更新的值,注意:这里插入的值是20不是30

db.person.update({"age":30},{$set:{"age":20}},{multi:true,upsert:true})

可以省略multi,upsert,这里不能有花括号,但是不建议这样做

db.person.update({"age":30},{$set:{"age":20}},true,true)

//值更新为数组

db.person.update({"name":"zhang"},{$set:{"age":[10,12,14]}},{upsert:true})

//修改为其它的值

db.person.update({"name":"zhang"},{$set:{"age":''}},{upsert:true})

db.person.update({"name":"zhang"},{$set:{"age":null}},{upsert:true})

$inc修改符

用于增加已有键的值,如果键不存在就创建,只能用于整形、长整型、浮点型。

//将name=zhang的记录的age键+10

db.person.update({"name":"zhang"},{$inc:{"age":10}},{upsert:true})

//将name=zhang的记录的age键-10

db.person.update({"name":"zhang"},{$inc:{"age":-10}},{upsert:true})

$unset修改符

删除键类似关系数据库的删除字段操作,要区别$set修改符的将键设空或者null值

db.person.update({"name":"zhang"},{$unset:{"age":1}})

  注:有关数组更新操作的就不在这里说明了!

 

八、删除 

1)删除整体数据

  db.goods.remove({name:xiaomi})

2 )删除某条数据的某个字段

  db.goods.remove({name:xiaomi},{'$unset':{name:1}})  或  db.goods.remove({name:xiaomi},{'$unset':{name:0}})

注:

  1、remove() 方法 并不会真正释放空间。需要继续执行 db.repairDatabase() 来回收磁盘空间。

  2、remove() 方法已经过时了,现在官方推荐使用  deleteOne() :删除符合条件的一条数据、 deleteMany()——删除符合条件的多条数据。

九、索引

从mongoDB 3.0开始ensureIndex被废弃,使用 createIndex创建索引。创建索引,需要传递两个参数 ①:建立索引的字段名称,②排序参数   1升序,-1降序。

1)建立单索引。

db.student.createIndex({name:1})   表示给name字段建立索引,按照升序的排序

2)建立复合索引。

db.student.ensureIndex({name:1,age:-1})  建立一个复合索引,表示给name和age都建立索引,按照name的升序,和age的降序

十、总结

MongoDB系列:二、MongoDB常用操作练习的更多相关文章

  1. MongoDB系列二

    简介 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案.  MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql ...

  2. MongoDB副本集的常用操作及原理

    本文是对MongoDB副本集常用操作的一个汇总,同时也穿插着介绍了操作背后的原理及注意点. 结合之前的文章:MongoDB副本集的搭建,大家可以在较短的时间内熟悉MongoDB的搭建和管理. 下面的操 ...

  3. MongoDB 副本集的常用操作及原理

    本文是对MongoDB副本集常用操作的一个汇总,同时也穿插着介绍了操作背后的原理及注意点. 结合之前的文章:MongoDB副本集的搭建,大家可以在较短的时间内熟悉MongoDB的搭建和管理. 下面的操 ...

  4. mongodb系列之--mongodb 主从配置与说明

    一.为什么要配置mongodb的主从: 1.做主从,可以说是做数据的备份,有利于故障的恢复 2.做主从,可以做到读写分离,主节点负责写操作,从节点负责读操作,这样就把读写压力分开,保证系统的稳定性. ...

  5. 【Redis使用系列】Redis常用操作

    一.string类型的常用命令 set key value   #一个key对应一个value.多次赋值,会覆盖前面. setnx key value  #如果key存在则创建key1,并返回1,如果 ...

  6. .Net Excel操作之NPOI(二)常用操作封装

    一.Excel数据导出常用操作 1.指定表头和描述 2.指定数据库中读出的数据集合 二.ExcelExport封装 /// <summary> /// Excel常用的表格导出逻辑封装 / ...

  7. MongoDB 系列(二) C# 内嵌元素操作 聚合使用

    "_id" : "639d8a50-7864-458f-9a7d-b72647a3d226","ParentGuid" : "00 ...

  8. MongoDB系列二(介绍).

    一.特点 学习一个东西,至少首先得知道它能做什么?适合做什么?有什么优缺点吧? 传统关系型数据库,遵循三大范式.即原子性.唯一性.每列与主键直接关联性.但是后来人们慢慢发现,不要把这些数据分散到多个表 ...

  9. MONGODB(二)——索引操作

    一.1.插入10w条数据> for(var i = 0;i<100000;i++){... var rand = parseInt(i*Math.random());... db.pers ...

  10. MongoDB系列二:MongoDB安装过程

    一.MongoDB安装,以Linux系统安装为例:(下载:www.mongodb.org 注意使用stable版本) 1.下载最新版本的MongoDB安装包,wget http://fastdl.mo ...

随机推荐

  1. TabLayoutViewPagerDemo【TabLayout+ViewPager可滑动】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用TabLayout搭配ViewPager实现可滑动的顶部选项卡效果. 效果图 代码分析 1.演示常规的设置. 2.通过自定义Vi ...

  2. Java进阶篇设计模式之四 -----适配器模式和桥接模式

    前言 在上一篇中我们学习了创建型模式的建造者模式和原型模式.本篇则来学习下结构型模式的适配器模式和桥接模式. 适配器模式 简介 适配器模式是作为两个不兼容的接口之间的桥梁.这种类型的设计模式属于结构型 ...

  3. 获得当前EIP的值

    VS2017 内联汇编 __asm { call NEXT NEXT: pop eax }

  4. 【带着canvas去流浪(7)】绘制水球图

    目录 一. 任务说明 二. 重点提示 三. 示例代码 四. 文字淹水效果的实现 五. 关于canvas抗锯齿 六. 小结 示例代码托管在:http://www.github.com/dashnowor ...

  5. docker daemon 配置文件

    Ubuntu Ubuntu 14.04 配置文件位于 /etc/init/docker.conf Ubuntu 15.04 配置文件位于 /etc/default/docker,修改配置项DOCKER ...

  6. C# 中 equals( ) 和 == 的区别和用法

    Equals: 下面的语句中,x.y 和 z 表示不为 null 的对象引用. * 除涉及浮点型的情况外,x.Equals(x) 都返回 true. * x.Equals(y) 返回与 y.Equal ...

  7. connection holder is null新增解决方案(2018-06-02)

    最近在做Java后台的项目,用到了druid数据库连接池,阿里出品,肯定是精品的意思咯,这也是我们老大搭建的框架,我就站在前人的肩膀上飞翔了.先前在一个事物里,使用了多条数据库操作,都是正常的,但是前 ...

  8. vue-router 通过路由来实现切换头部标题

    在做单页面应用程序时,一般页面布局头尾两块都是固定在布局页面,中间为是路由入口.这时访问页面时头部标题不会变,该问题的解决方案如下: 通过采用组件内路由卫士(beforeRouterEnter.bef ...

  9. .net开源工作流引擎ccflow Pop返回值设置

    关键词: 点击字段弹出返回值填充文本框或其他字段     表单自动填充   .net开源工作流  jflow工作流   ccflow   工作流引擎 应用场景 当我们的查询信息比较多我们希望有一个比较 ...

  10. 【设计模式】简单工厂模式 Simple Factory Pattern

    简单工厂模式Simple Factory Pattern[Simple Factory Pattern]是设计模式里最简单的一个模式,又叫静态工厂模式[Static Factory Pattern], ...