1、MongoDb 介绍
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像 关系数据库的。他支持的数据结构非常松散,是类似 json 的 bson 格式,因此可以存储比较复杂的数据类型。Mongo 最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。它的特点是高性能、易部署、 易使用,存储数据非常方便。
2、MongoDb 安装
官网:https://www.mongodb.com/
手册:https://docs.mongodb.org/manual/
1、双击 MongoDB 软件下一步下一步安装
注意:安装路径不能有中文,存放地点的盘符也不能是中文,否则会安装出错。
2、配置环境变量
在环境变量path那里加上MongoDB的bin文件目录,我的是F:\Mongo\bin
3、使用MongoDB
(1)数据库使用
1、新建一个存放数据库的文件夹,注意:不能有中文和空格,建议不要放在C盘
这里我建的路径为:F:\MongoDB
2、启动MongoDb服务
服务端:mongod 开启数据库服务 mongod --dbpath F:\MongoDB
注意:上面是开启服务,在不关闭上面这个窗口的基础上,新打开一个窗口
上面那个admin和config那些数据库是系统自带的
3、客户端输入 mongo 命令连接服务端
-
客户端:mongo 使用数据库
-
客户端:mongo 使用数据库 ip 地址:端口号
清屏:
cls
查看所有数据库列表
show dbs
(2)创建数据库
假设我们要创建如下数据库
- 使用数据库、创建数据库
use 数据库名
eg: use student
注意:如果真的想把这个数据库创建成功,那么必须插入一个数据。 数据库中不能直接插入数据,只能往集合(collections也就是表)中插入数据。不需要专门创建集合,只 需要写点语法插入数据就会创建集合:
db.student.insert({“name”:”xiaoming”});
db.student
,系统发现 student 是一个陌生的集合名字,所以就自动创建了集合。
- 显示所有数据库
show dbs
- 显示当前的数据集合(mysql 中叫表)
show collections
- 删除数据库,删除当前所在的数据库
db.dropDatabase();
- 删除集合,删除指定的集合 删除表 (db.collection_name.drop())
db.user.drop()
(3)插入(增加)数据
插入数据,随着数据的插入,数据库创建成功了,集合也创建成功了。
db.表名.insert({"name":"zhangsan"}); student 集合名称(表)
(4)查找数据
1、查询所有记录
db.userInfo.find();
相当于:select* from userInfo;
2、查询去掉后的当前聚集集合中的某列的重复数据
db.userInfo.distinct("name");
会过滤掉 name 中的相同数据 相当于:select distict name from userInfo;
3、查询 age = 22 的记录
db.userInfo.find({"age": 22});
相当于:select * from userInfo where age = 22;
4、查询 age > 22 的记录
db.userInfo.find({age: {$gt: 22}});
相当于:select * from userInfo where age >22;
5、查询 age < 22 的记录
db.userInfo.find({age: {$lt: 22}});
相当于:select * from userInfo where age <22;
6、查询 age >= 25 的记录
db.userInfo.find({age: {$gte: 25}});
相当于:select * from userInfo where age >= 25;
7、查询 age <= 25 的记录
db.userInfo.find({age: {$lte: 25}});
8、查询 age >= 23 并且 age <= 26 注意书写格式
db.userInfo.find({age: {$gte: 23, $lte: 26}});
9、查询 name 中包含 mongo 的数据 模糊查询用于搜索
db.userInfo.find({name: /mongo/});
//相当于%%
select * from userInfo where name like ‘%mongo%’;
10、查询 name 中以 mongo 开头的
db.userInfo.find({name: /^mongo/});
select * from userInfo where name like ‘mongo%’;
11、查询指定列 name、age 数据
db.userInfo.find({}, {name: 1, age: 1});
相当于:select name, age from userInfo;
当然 name 也可以用 true 或 false,当用 ture 的情况下河 name:1 效果一样,如果用 false 就 是排除 name,显示 name 以外的列信息。
12、查询指定列 name、age 数据, age > 25
db.userInfo.find({age: {$gt: 25}}, {name: 1, age: 1});
相当于:select name, age from userInfo where age >25;
13、按照年龄排序 1 升序 -1 降序
升序:db.userInfo.find().sort({age: 1});
降序:db.userInfo.find().sort({age: -1});
14、查询 name = zhangsan, age = 22 的数据
db.userInfo.find({name: 'zhangsan', age: 22});
相当于:select * from userInfo where name = ‘zhangsan’ and age = ‘22’;
15、查询前 5 条数据
db.userInfo.find().limit(5);
相当于:selecttop 5 * from userInfo;
16、查询 10 条以后的数据
db.userInfo.find().skip(10);
相当于:select * from userInfo where id not in ( selecttop 10 * from userInfo );
17、查询在 5-10 之间的数据
db.userInfo.find().limit(10).skip(5);
可用于分页,limit 是 pageSize,skip 是第几页pageSize*
18、or 与 查询
db.userInfo.find({$or: [{age: 22}, {age: 25}]});
相当于:select * from userInfo where age = 22 or age = 25;
19、findOne 查询第一条数据
db.userInfo.findOne();
相当于:selecttop 1 * from userInfo;
db.userInfo.find().limit(1);
20、查询某个结果集的记录条数 统计数量
db.userInfo.find({age: {$gte: 25}}).count();
相当于:select count(*) from userInfo where age >= 20;
如果要返回限制之后的记录数量,要使用 count(true)或者 count(非 0) db.users.find().skip(10).limit(5).count(true);
(5)修改数据
修改里面还有查询条件。你要改谁,要告诉 mongo。
- 查找名字叫做小明的,把年龄更改为 16 岁:
db.student.update({"name":"小明"},{$set:{"age":16}});
- 查找数学成绩是 70,把年龄更改为 33 岁:
db.student.update({"score.shuxue":70},{$set:{"age":33}});
- 完整替换,不出现$set 关键字了:
db.student.update({"name":"小明"},{"name":"大明","age":16});
注意:上面这个例子完全替换了,不出现set关键词了
(6)删除数据
db.collectionsNames.remove( { "borough": "Manhattan" } )
db.users.remove({age: 132});
db.restaurants.remove( { "borough": "Queens" }, { justOne: true } )
4、MongoDB 索引 和 explain 的使用
(1)索引基础
索引是对数据库表中一列或多列的值进行排序的一种结构,可以让我们查询数据库变得更快。MongoDB 的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的查询优化技巧。
- 下面是创建索引的命令:
db.user.ensureIndex({"username":1})
- 获取当前集合的索引
db.user.getIndexes()
- 删除索引的命令是
db.user.dropIndex({"username":1})
- 创建复合索引
数字1表示username
键的索引按升序存储,-1表示age
键的索引按降序方式存储。
db.user.ensureIndex({"username":1,"age":-1})
该索引被创建后,基于 username 和 age 的查询将会用到该索引,或者是基于 username 的查询也会用到该索引,但是只是基于 age 的查询将不会用到该复合索引。因此可以说,如果想用到复合索引,必须在查询条件中包含复合索引中的前N个索引列。然而如果查询条件中的键值顺序和复合索引中的创建顺序不一致的话,MongoDB 可以智能的帮助我们调整该顺序,以便使复合索引可以为查询所用。如:
db.user.find({"age":30,"username":"stephen"})
对于上面示例中的查询条件,MongoDB在检索之前将会动态的调整查询条件文档的顺序,以使该查询可以用到刚刚创建的复合索引。
对于上面创建的索引,MongoDB 都会根据索引的 keyname 和索引方向为新创建的索引 自动分配一个索引名,下面的命令可以在创建索引时为其指定索引名,如:
db.user.ensureIndex({"username":1},{"name":"userindex"})
随着集合的增长,需要针对查询中大量的排序做索引。如果没有对索引的键调用 sort, MongoDB 需要将所有数据提取到内存并排序。因此在做无索引排序时,如果数据量过大以 致无法在内存中进行排序,此时 MongoDB 将会报错。
(2)唯一索引
- 在缺省情况下创建的索引均不是唯一索引。下面的示例将创建唯一索引,如:
db.user.ensureIndex({"userid":1},{"unique":true})
- 如果再次插入 userid 重复的文档时,MongoDB 将报错,以提示插入重复键,
db.user.insert({"userid":5})
db.user.insert({"userid":5})
上面将会报错:E11000 duplicate key error index: user.user.$userid_1 dup key: { : 5.0 }
如果插入的文档中不包含 userid 键,那么该文档中该键的值为 null,如果多次插入类似 的文档,MongoDB 将会报出同样的错误,
-
如果在创建唯一索引时已经存在了重复项,我们可以通过下面的命令帮助我们在创建唯 一索引时消除重复文档,仅保留发现的第一个文档,如:
- 先删除刚刚创建的唯一索引。
db.user.dropIndex({"userid":1})
- 插入测试数据,以保证集合中有重复键存在
db.user.remove()
db.user.insert({"userid":5})
db.user.insert({"userid":5})
- 重新创建唯一索引
db.user.ensureIndex({"userid":1},{"unique":true })
-
我们同样可以创建复合唯一索引,即保证复合键值唯一即可。如:
db.user.ensureIndex({"userid":1,"age":1},{"unique":true})
(3)索引的一些参数
如果在为已有数据的文档创建索引时,可以执行下面的命令,以使 MongoDB 在后台创 建索引,这样的创建时就不会阻塞其他操作。但是相比而言,以阻塞方式创建索引,会使整 个创建过程效率更高,但是在创建时 MongoDB 将无法接收其他的操作。
db.user.ensureIndex({"username":1},{"background":true})
(4)使用explain
explain 是非常有用的工具,会帮助你获得查询方面诸多有用的信息。只要对游标调用 该方法,就可以得到查询细节。explain 会返回一个文档,而不是游标本身。如:
explain 会返回查询使用的索引情况,耗时和扫描文档数的统计信息。
(5)explain executionStats 查询具体的执行 时间
db.tablename.find().explain( "executionStats" )
关注输出的如下数值:explain.executionStats.executionTimeMillis