上一篇博文中,我详细描述了从MongoDB简介到安装,在本节,主要从整体角度去看MongoDB。
MongoDB的数据架构
官方是这样描述的
MongoDB stores all documents in collections. A collection is a group of related documents that have a set of shared common indexes. Collections are analogous to a table in relational databases.
根据其描述,可以大致归纳MongoDB的结果如下图:
解析:一个数据库(Database)中可以包含多个集合(colection),每个集合中,可以包含多个文档。可以类比,SQL数据库,一个数据库中包含多个表,每个表中包含多个记录。
命令规范
数据库命令
1.任意UTF-8(中文也行)
2.不能是空字符串
3.不得包含以:’空格’、’.’ 、’$’、’/’、’\’、’\0’。
4.长度不得超过64字节.
5.不能使用保留字:admin、local、config
集合
1.任意的UTF-8字符串
2.不能是空的字符串
3.不能包含\0、$
4.不能以system.开头
文档
1.任意的UTF-8字符串
2.不能是空字符串
3.不能包含\0、$
4.不能以_开头
数据类型
官方提示MongoDB支持类型有如下:
null null用于表示空值或者不存在的字段。 {“tmpkey”:null}
布尔 布尔类型有两个值’true’和’false1’. {“tmpkey”:true}
32位整数 类型不可用。JavaScript仅支持64位浮点数,所以32位整数会被自动转换。
64位整数 不支持这个类型。shell会使用一个特殊的内嵌文档来显示64位整数
64位浮点数 shell中的数字都是这种类型。下面的表示都是浮点数: {“tmpkey” : 5.12}
字符串 UTF-8字符串都可表示为字符串类型的数据: {“tmpkey” : “abf”}
符号 不支持这种类型。shell将数据库里的符号类型转换成字符串。
对象id 对象id是文档的12字节的唯一 ID, {“tmpkey” :ObjectId() }
日期 日期类型存储的是从标准纪元开始的毫秒数。不存储时区: {“tmpkey” : new Date()}
正则表达式 文档中可以包含正则表达式,采用JavaScript的正则表达式语法: {“tmpkey” : /\w/i}
代码 文档中还可以包含JavaScript代码:{“tmpkey” : function() { /* …… */ }}
二进制数据 二进制数据可以由任意字节的串组成。不过shell中无法使用。
最大值 BSON包括一个特殊类型,表示可能的最大值。shell中没有这个类型。
最小值 BSON包括一个特殊类型,表示可能的最小值。shell中没有这个类型。
未定义 文档中也可以使用未定义类型:{“tmpkey”:undefined}
数组 值的集合或者列表可以表示成数组:{“tmpkey” : [“a”, “b”, “c”]}
内嵌文档 文档可以包含别的文档,也可以作为值嵌入到父文档中,数据可以组织得更自然些,不用非得存成扁平结构的:{“tmpkey” : {“color” : “yello”}}
MongoDB集合的操作
在学习mongoDB集合的时候,可以将其类比SQL数据库中的表。
创建集合
1.显示创建
创建之前,我们先建立一个数据库,关于数据库的建立,可以参考上一篇文章(http://blog.csdn.net/hsd2012/article/details/51279472)
我们知道,在SQL数据库中,我们使用show tables查看包含的表,那么在MongoDB怎样才能查看当前数据库中包含的集合呢?此时使用的是show collections;
student代表集合,system.indexes代表MongoDB的索引。
2.隐式创建
db.class.insert({‘classid’:1,’className’:”三年二班”});
代表网class集合中插入一个文档(班级编号为1,班级名称为三年二班)。本质是,往一个集合中插入一条数据,如果这个集合不存在,mongoDB会自动帮我们创建该集合。
显示数据库中所有集合
下面两条命令都可以实现显示所有的集合。
show collections
show tables
删除集合
db.collectionName.drop();
MongoDB文档的操作
在学习mongoDB文档的时候,可以将其类比SQL数据库表中的数据。数据库表中每一行,可以类比中集合中每一个文档。
数据的插入
MongoDB中数据插入,指的是将创建的文档,插入到指定的集合中。
命令如下:
db.collectionName.insert(doc);
官方文档提示:
The operation will create the collection if the collection does not currently exist
Insert a document into a collection
Insert an Array of Documents
如果集合不存在,则创建该集合。doc可以为一个集合或者一个集合数组。
1.向school数据库的student集合中,插入一个文档。
db.student.insert({"stu_id":1,"stu_name":"张三","age":6,"class_id":1});
通过db.student.find();查找集合中的数据,我们可以看到,刚刚我们插入的数据。那么”_id”是什么意思呢?这是MongoDB自动生成的一个全球唯一的主键,用于区分文档。其包含四部分:时间戳、机器、PID(进程号)、计数器。
1.向school数据库的student集合中,插入多个文档。
var docArr=[{"stu_id":2,"stu_name":"李四"},{"stu_id":3,"stu_name":"王五","class_id":1},{"stu_id":4,"stu_name":"赵六",age:10,"hobby":"football"}];
db.student.insert(docArr);
代码执行效果如下:
数据删除
命令如下:
db.collectionName.remove(where,[justOne]);
where 代表删除条件,当where为{}代表删除所有文档。
justOne 默认情况下为false,代表匹配条件的文档有多个的时候,删除所有的匹配文档。如果设置为true或1(设置其他非0的整数也可以),代表仅仅删除一个文档。
实例
1.删除school数据库student集合里名字(stu_name)为赵六的文档。
db.student.remove({"stu_name":"赵六"});
代码执行效果如下:
2.删除school数据库student集合里班级编号(class_id)为1的一个集合。
为了便于操作,我先往student集合里面添加了一些文档,此时集合中文档数据内容如下:
可以发现,class_id为1的集合有4个。
db.student.remove({"class_id":1},2);
执行结果如下:
可以发现,虽然满足条件的文档很多,但是仅仅删除了其中一个文档。
数据修改
在mongoDB中修改数据(文档),是通过如下命令来实现的
db.collectionName.update(query,update,upset,multi);
collectionName:集合名字
query: 修改的条件,类似SQL的where语句。
update :更新命令,类似SQL的set语句。
upset :可选,默认是false,如果未发现符合更新条件的数据内容,是否执行插入操作,1或者true代表进行插入 0或者false不进行插入。
multi :可选,mongodb 默认是false。是否进行多行更新。1或者true进行多行更新 0或者false不进行多行更新。
关于update 格式有两种形式
1.直接赋值使用{set:{}}
如{set:{“name”:”张三”}},将名字改为张三
2.进行算术运算使用{inc:{}}
如{inc:{“age”:3}},将age增加3
如{$inc:{“age”:-3}},将age减3
实例
1.更新学生编号(stu_id)为2文档,为其添加一个字段年龄(age)为13
db.student.update({"stu_id":2},{$set:{"age":13}});
执行结果如下:
2.更新学生,将其年龄(age)设置为12
db.student.update({},{$set:{"age":12}},0,1);
3.将班级编号为2的所有学生,年龄(age)增加1
代码如下
db.student.update({"class_id":2},{$inc:{"age":1}},0,1);
执行效果如下图
数据查询
基本的查询操作
1.查询集合中的所有文档
db.collectionName.find();
例题:查找集合student中所有数据。
为了便于查找,先向其中插入一些数据
for(var i=0;i<20;i++){
db.student.insert({"stu_id":9+i,"stu_name":"赵"+i});
}
db.student.find();
执行结果如下
2.查询集合中的第一个文档
db.collectionName.findOne();
条件查询
1.MongoDB中查询条件
数据查询条件 | MongoDB中 | 应用实例讲解 |
---|---|---|
等于(=) | ---- |
查找名字为李四的所有学生db.student.find({“name”:”李四”}); |
等于(!=) | $ne |
查找名字为李四的所有学生db.student.find({"name":{$ne:"李四"}}); |
大于(>) | $gt |
查找所有年龄大于5的学生db.student.find({"age":{$gt:5}}); |
大于(<) | $lt |
查找所有年龄小于15的学生db.student.find({"age":{$lt:15}}); |
大于等于(>=) | $gte |
查找所有年龄大于或等于5的学生db.student.find({"age":{$gte:5}}); |
小于等于(>=) | $lte |
查找所有年龄小于或等于15的学生db.student.find({"age":{$lte:15}}); |
与(and) | ---- |
查找所有年龄小于或等于15且班级编号为1的所有学生db.student.find({"age":{$lte:15},"class_id":1}); |
或(or) | {$or:[{条件1},{条件2}]} |
查找所有年龄小于或等于15或者班级为1的所有学生db.student.find({$or:[{"age":{$lte:15}},{"class_id":1}]}); |
非或(nor) | {$nor:[{条件1},{条件2}]} |
条件1不能满足和条件2不能满足。 |
集合运算符(in) | {$in |
查找年龄12或者13或者14的学生。db.student.find({"age":{$in:[12,13,14]}}); |
集合运算符(all) | {$all |
查找爱好包含football,和basketBall的所有学生db.student.find({"hobby":{$all:["football","basketBall"]}}); |
是否存在(exists) | {$exists |
查询存在hooby的所有学生db.student.find({hobby:{$exists:1}}) ,{$exists:0}代表不存在 |
统计、排序、分页
1.统计
db.collectionName.count();
db.collectionName.find().count();
2.排序
db.collectionName.find().sort({key:1});//key升序排列
db.collectionName.find().sort({key:-1});//key降序排列
3.分页
db.collectionName.find().skip(n).limit(m);
解析:从collectionName中第n个文档开始读取,共读取m个文档,需要注意的是MongoDB中n是从0开始的。可以类比Mysql中limit方法。n相当于limit中的第一个方法,m相当于limit中第二个参数
当使用分页时候,若使用count,需要注意mongoDB统计数量默认是忽略分页的,看下图:
怎样让其不忽视分页呢?这时候需要给count传递一个参数count(flag)。flag为0(默认情况为0)忽视分页,flag为1,不忽视分页。
实例:
1.从student中取出6~12条数据
db.student.find().skip(6).limit(6);
2.从集合student中取出第一条数据
db.student.find().skip(0).limit(1);
投影查询
在MongoDB中,上面讲的每次查询都是将所有的键都显示出来了,怎样只让部分键显示呢?这就要用到投影查询。
比如,我只让集合student查询结果中stu_name显示。
db.student.find({},{_id:0,stu_id:0});
解析:在mongoDB中,find函数里面的第二个参数是用来控制让哪些键显示或者不显示。0是不显示,1为显示。默认情况下,为显示。
备注
清空屏幕
cls命令