nodejs项目实战教程13——MongoDB

nodejs项目实战教程13——MongoDB

1. NoSql简介

建议直接看NoSql的百度百科,介绍的很详细。这里简单概括下:

NoSQL最常见的解释是“non-relational”, “Not Only SQL”也被很多人接受。NoSQL仅仅是一个概念,泛指非关系型的数据库,区别于关系数据库,它们不保证关系数据的ACID特性。NoSQL是一项全新的数据库革命性运动,其拥护者们提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。

优点:易扩展,NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。无形之间也在架构的层面上带来了可扩展的能力。大数据量,高性能,NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。

2. MongoDB简介

MongoDB是NoSql的一种文档型数据库,一个介于关系数据库和非关系数据库之间的产品,是非关系数据库中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似Json的Bjson格式,因此可以存储比较复杂的数据类型。MongoDB最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,还支持为数据建立索引。它的特点是高性能、易部署、易使用、存储数据非常方便。

主要功能特性:
1)面向集合存储,易存储对象类型的数据。
“面向集合”( Collenction-oriented),意思是数据被分组,存储在数据集中,被称为一个集合。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库里的表,不同的是它不需要定义任何模式( Schema)。
2)模式自由。
模式自由,意味着对于存储在Mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。

3. MongoDB安装

前往MongoDB官网,选择Community Server
在这里插入图片描述
选择对应的版本,点击Download下载
在这里插入图片描述
下载后双击安装,过程可以选择自定义目录
在这里插入图片描述
安装完成后进行环境配置,找到安装后的MongoDB的bin目录,加入到系统变量的path目录中
在这里插入图片描述
打开cmd,输入mongo查看版本并建立连接,show dbs 查看当前存在的数据库,初始化时有3个内置的数据库,分别是admin、config、local,不要动它们。
在这里插入图片描述

4. MongoDB基础操作——增删改查

注意,每次进行MongoDB操作之前需要先在cmd中执行一次mongo操作建立数据库连接。

mongo

cls可以清空之前的输入和输出内容

cls

4.1 数据库的增删改查

4.1.1 查看数据库

show dbs

在这里插入图片描述

4.1.2 使用和创建数据库

切换到对应的数据库

use 数据库名称

在这里插入图片描述
但是此时并没有实际生成该数据库,直到往其中插入第一条数据
在这里插入图片描述

4.1.3 查看当前数据库的集合(mysql中也叫做表)

show collections

在这里插入图片描述

4.1.4 查看当前数据库某个集合的数据

db.集合名称.find()

在这里插入图片描述

4.1.5 删除当前数据库的某个集合

db.集合名称.drop()

在这里插入图片描述

4.1.6 删除数据库

db.dropDatabase()

在这里插入图片描述
删除数据库前需要使用 use 数据库名称 先切换到该数据库。

4.2 插入数据

db.集合名称.insert({"name":"admin","age":20})

和关系型数据库不同的是,集合(mysql中也叫做表)每次插入的数据字段名称可以不同,值的类型也可以不同。

4.3 查询数据

4.3.1 查询集合所有数据

db.集合名称.find()

在这里插入图片描述

4.3.2 查询 age = 22 的记录

find.集合名称.find({"age":22})

在这里插入图片描述

4.3.3 查询 age > 22 的记录

db.集合名称.find({"age":{$gt:22}})

在这里插入图片描述

4.3.4 查询 age < 22 的记录

db.集合名称.find({"age":{$lt:22}})

在这里插入图片描述

4.3.5 查询 age >= 23 的记录

db.集合名称.find({"age":{$gte:22}})

在这里插入图片描述

4.3.6 查询 age <= 23 的记录

db.集合名称.find({"age":{$lte:22}})

在这里插入图片描述

4.3.7 查询 age >= 22 并且 age <=25 的记录

db.集合名称.find({"age":{$gte:22,$lte:25}})

在这里插入图片描述

4.3.8 查询 name 中包含 zhang 的记录 (模糊查询)

db.集合名称.find({name:/zhang/})

在这里插入图片描述

4.3.9 查询 name 中以 zh 开头的记录

db.集合名称.find({name:/^zh/})

在这里插入图片描述

4.3.10 查询以 i 结尾的记录

db.集合名称.find({name:/i$/})

在这里插入图片描述

4.3.11 查询指定列的记录

db.集合名称.find({},{name:1})

第一个{}表示查询条件为空,{name:1}表示筛选name这一列,只要第二个{}中的筛选列后面跟着Boolean值为true的值都可以,即 db.user.find({},{name:1}) 等价于 db.user.find({},{name:true}) 等价于 db.user.find({},{name:20})。至于_id是记录id,每次查询都会有。
在这里插入图片描述

4.3.12 查询指定列 name、age 数据,age > 23

db.集合名称.find({age:{$gt:23}},{name:1,age:1})

在这里插入图片描述

4.3.13 按照年龄排序 1升序 -1排序

升序:

db.集合名称.find().sort({age:1})

降序:

db.集合名称.find().sort({age:1})

在这里插入图片描述

4.3.14 查询 name = zhangsan,age = 23 的记录 (多条件查询)

db.集合名称.find({name:"zhangsan",age:25})

在这里插入图片描述

4.3.15 查询前 3 条记录

db.集合名称.find().limit(3)

在这里插入图片描述

4.3.16 查询 3 条之后的记录

db.集合名称.find().skip(3)

在这里插入图片描述

4.3.17 查询 4-5 之间的记录 (通常用于分页查询)

db.集合名称.find().skip(3).limit(2)

或者

db.集合名称.find().limit(2).skip(3)

用于分页时,limit 是 pageSize,skip 是 (page-1) * pageSize
![在这里插入图片描述](https://img-blog.csdnimg.cn/81c39bf7b6a04b21ae1269c767baa466.png

4.3.18 查询 第一条 记录

db.集合名称.findOne()

在这里插入图片描述

4.3.19 查询 age = 22 或者 age = 30 的记录

db.集合名称.find({$or:[{age:22},{age:30}]})

在这里插入图片描述

4.3.20 查询某个结果集合的记录总条数

db.集合名称.find({age:{$gte:30}}).count()

在这里插入图片描述
如果要返回限制之后的记录数量,需要使用count(true)或者count(任何非0数)

db.集合名称.find().skip(3).limit(10).count(true)

在这里插入图片描述

4.3.21 批量创建记录

删除之前的user集合,重新创建一个admin集合。在MongoDB中可以使用JavaScript批量创建记录,使用for循环,输入

for(vari = 0;i < 100;i++){

回车后,在mongo状态模式中,cmd会判断该语句还处于编辑状态中,继续输入插图插入语句

db.admin.insert("name":"zhangsan"+i,"age":i)

继续回车,直到输入

}

cmd才会认为结束编辑,执行一整条for循环。

在这里插入图片描述

4.4 修改数据

创建一个student表用于修改数据演示:
在这里插入图片描述

4.4.1 修改某条记录的某个属性

db.集合名称.update({"name":"lisi"},{$set:{"age":8}})

把名字叫做lisi的年龄修改为8

在这里插入图片描述

4.4.2 修改符合条件的所有记录的某个属性

db.集合名称.update({"age":8},{$set:{"grade":2}},{multi:true})

{multi:true} 用于批量修改符合条件的记录,如果不加则至修改第一条符合条件的记录。
在这里插入图片描述

4.4.3 替换整条记录

db.集合名称.update({"name":"zhaosi"},{"name":"zhaozilong","age":7})

替换名字为zhaosi的学生记录为名字改成zhaozilong,年龄改为7
在这里插入图片描述

4.5 删除数据

同学们,这一部分可得学好了😎

4.5.1 删除所有符合条件的记录

db.集合名称.remove({"name":"zhangsan"})

把所有叫做张三的同学都给删除了

在这里插入图片描述

db.admin.remove({"age":{$gt:20}})

删除admin集合中年龄大于20岁的记录
在这里插入图片描述

4.5.2 删除第一条符合条件的记录

db.集合名称.remove({"age":7},{justOne:true})

只删除一条年龄为7的记录
在这里插入图片描述

5. MongoDB 进阶

5.1 索引

添加索引可以大大优化查询记录的时间。创建user集合,插入60万条数据,用于比较添加索引后的查询时间。
在这里插入图片描述
增加索引会大大增加查询效率,但是同时也会让新增和删除操作慢一些

5.1.1 查看查询时间

db.集合名称.find({"name":"zhangsan456"}).explain("executionStats")

本次查询名字是zhangsan456的记录所用时间为302毫秒
在这里插入图片描述

5.1.2 查看查询的索引

db.集合名称.getIndexes()

查询出一个对象数组,说明索引可以是多个,默认索引为字段id,即_id,名称为_id_
在这里插入图片描述

5.1.2 添加索引

db.集合名称.createIndex({"name":1})

将name字段作为索引,此时再次查看索引,可以看到新索引的名称为name_1

在这里插入图片描述
新增索引之后的查询时间为1毫秒,效率相差了几百倍。因此,当有海量数据需要进行查询时,添加索引必不可少。
在这里插入图片描述

5.1.3 删除索引

db.集合名称.dropIndex({"name":1})

在这里插入图片描述
此时再次查询就会恢复到原来的速度。

5.1.4 添加复合索引

 db.集合名称.createIndex({"name":1,"No":1})

在这里插入图片描述
添加复合索引后,使用索引中的第一个或者所有条件查询都可以加快查询速度,但是使用第二个条件是是无法为索引提速的。

db.集合名称.find({"name":"zhangsan456","No":456}).explain("executionStats")

使用复合索引所有条件查询,很快,1毫秒不到。
在这里插入图片描述

db.集合名称.find({"name":"zhangsan456"}).explain("executionStats")

使用复合索引的第一个条件查询,还是1毫秒不到。
在这里插入图片描述

 db.集合名称.find({"No":"456"}).explain("executionStats")

使用第二个条件查询,575毫秒,说明复合索引完全无效。相当于使用默认索引的时间。
在这里插入图片描述

5.1.5 添加唯一索引

 db.集合名称.createIndex({"name":1},{"unique":true})

先切换到admin集合,添加一条名称相同的记录,再执行添加唯一索引操作,看看会发生什么:
在这里插入图片描述
结果是,无法再使用name作为唯一索引,添加name为唯一索引会失败。但是如果将原来的名称重复的记录删除,即可重新添加name为唯一索引:
在这里插入图片描述
此时如果再次添加相同名称的记录就会失败:
在这里插入图片描述
当然,如果你愿意的话,也可以建立复合索引,只需要保证复合键唯一即可。

5.2 账户权限

5.2.1 创建超级管理员

切换到MongDB自带的admin数据库

use admin

创建超级管理员

db.createUser({ user:'admin', pwd:'123456', roles:[{role:'root',db:'admin'}] })

查看当前库的用户列表,默认是没有用户的,直到我们添加。

show users 

在这里插入图片描述

5.2.2 修改MongoDB数据库配置文件

用记事本或者其他编辑器打开MongoDB/bin/mongod.cfg文件,在编辑之前线备份一份,命名为mongod_bac.cfg。
在这里插入图片描述

配置安全设置,将#security:替换成

security: 
	authorization: enabled

在这里插入图片描述

5.2.3 重启MongoDB服务

修改完配置文件,还需要重启服务才能够生效。
在这里插入图片描述
在这里插入图片描述

5.2.4 使用超级管理员账号连接数据库

重新打开cmd,输入mongo,发现已经没有权限,无法查看。
在这里插入图片描述
重新打开cmd,输入

mongo admin -u 用户名 -p 密码

即可进入

在这里插入图片描述

5.2.5 创建某个数据库的用户,不能访问其他数据库

切换到某个数据库:

use sheldon

给该数据库添加用户:

db.createUser( { user: "sheldonadmin", pwd: "123456", roles: [ { role: "dbOwner", db: "sheldon" } ] })

在这里插入图片描述
重新打开cmd,输入:

mongo sheldon -u sheldonadmin -p 123456

只能看到该数据库

在这里插入图片描述

5.2.6 MongoDB数据库的角色

1.数据库用户角色:read、readWrite
2.数据库管理角色:dbAdmin、dbOwner、userAdmin
3.集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
4.备份恢复角色:backup、restore;
5.所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、 dbAdminAnyDatabase
6.超级用户角色:root

5.2.7 连接数据库时需要配置账户密码

const url = 'mongodb://admin:123456@localhost:27017/';

5.3 关系型数据库中集合(表)与集合(表)之间的几种关系

5.3.1 一对一关系

简单来说,就是两个集合A和B,B中最多只有一条记录和A对应。
比如A是身份证信息集合,有身份证id、姓名、性别、名族,B是驾驶证信息集合,有身份证id、驾驶证id,只有一个B的身份证id和A其中的一个身份证id对应,那么这两个集合就是一对一关系。换句话说,一一对应。

5.3.1 一对多关系

简单来说,就是两个集合A和B,B中可以有多条记录和A中的一条记录对应。
比如集合A是人,集合B是游戏账号,一个人可以有多个账号,但是每个账号只能被一个人拥有。

5.3.1 多对多关系

简单来说,就是两个集合A和B,B中可以有多条记录和A中的一条记录对应,A中也可以有多条记录和B中的一条记录对应。
最经典的案例就是一个学生可以选择多门课程,一门课程也可以被多人选择。

6. MongoDB高级

6.1 聚合管道

在实际项目中用于表的管理查询和数据统计。
先添加3个订单,order是订单表,order_item是订单详情表。用于演示学习。
在这里插入图片描述
订单一有3个订单商品,这就是典型的一对多关系。
在这里插入图片描述

6.1.1 $project——多用于筛选字段

修改文档的结构,用于重命名、增加或者删除文档中的字段。

db.order.aggregate([
	{
		$project:{trade_no:1,all_price:1}
	}
])

查询order表,只返回trader_no和all_price字段。此时作用和

db.order.find({},{trade_no:1,all_price:1})

一致,但是使用聚合管道可以用于多表查询。
在这里插入图片描述

6.1.2 $match——条件查询

db.order.aggregate([
	{
		$project:{trade_no:1,all_price:1}
	},
	{
		$match:{all_price:{$gte:100}}
	}
])

查询订单中总价超过100的订单,并输出trade_no和all_price两个字段。
在这里插入图片描述

6.1.3 $group——分组

db.order_item.aggregate([
	{
		$group:{_id:"$order_id",total:{$sum:"$price"}}
	}
])

对order_item表根据order_id字段进行分组,并计算每个分组的总价格。
在这里插入图片描述

6.1.4 $sort——排序

db.order.aggregate([
	{
		$project:{trade_no:1,all_price:1}
	},
	{
		$match:{all_price:{$gte:100}}
	},
	{
		$sort:{all_price:1}
	}
])

查询order表中总价大于100的记录,显示trade_no和all_price两个字段,并按照all_price升序排列({$sort:{all_price:-1}}时就是降序排列)。
在这里插入图片描述

6.1.5 $limit——最多显示几条,通常用于分页操作

db.order.aggregate([
	{
		$project:{trade_no:1,all_price:1}
	},
	{
		$match:{all_price:{$gte:100}}
	},
	{
		$sort:{all_price:-1}
	},
	{
		$limit:1
	}
])

在这里插入图片描述

6.1.6 $skip——显示多少条之后的记录

db.order.aggregate([
	{
		$project:{trade_no:1,all_price:1}
	},
	{
		$match:{all_price:{$gte:100}}
	},
	{
		$sort:{all_price:-1}
	},
	{
		$skip:1
	}
])

在这里插入图片描述

6.1.7 $lookup——联表查询

(1)示例1:order表关联order_item表查询

db.order.aggregate([
	{
		$lookup: { 
			from:"order_item", 
			localField:"order_id",
			foreignField:"order_id", 
			as:"items" 
		} 
	} 
])

关联order集合和order_item集合,将order_item集合的order_id字段和localField字段做匹配,符合条件的order_item记录放进对应的items字段中。(按照结果说,就是order集合中的每个记录添加一个items字段,值为order_item集合中的所有order_id与order集合中的所有记录)
在这里插入图片描述
结果:

{
	"_id": ObjectId("61c92596bbdd50138d2b6a7b"),
	"order_id": "1",
	"uid": 10,
	"trade_no": "111",
	"all_price": 10800,
	"all_num": 3,
	"items": [{
		"_id": ObjectId("61c92439bbdd50138d2b6a74"),
		"order_id": "1",
		"title": "Mac电脑1",
		"price": 10000,
		"num": 1
	}, {
		"_id": ObjectId("61c9246ebbdd50138d2b6a75"),
		"order_id": "1",
		"title": "雷蛇鼠标1",
		"price": 300,
		"num": 1
	}, {
		"_id": ObjectId("61c92481bbdd50138d2b6a76"),
		"order_id": "1",
		"title": "转接口1",
		"price": 500,
		"num": 1
	}]
} {
	"_id": ObjectId("61c925b0bbdd50138d2b6a7c"),
	"order_id": "2",
	"uid": 20,
	"trade_no": "222",
	"all_price": 90,
	"all_num": 2,
	"items": [{
		"_id": ObjectId("61c924abbbdd50138d2b6a77"),
		"order_id": "2",
		"title": "热狗12只",
		"price": 10,
		"num": 1
	}, {
		"_id": ObjectId("61c924c0bbdd50138d2b6a78"),
		"order_id": "2",
		"title": "牛奶一箱",
		"price": 80,
		"num": 1
	}]
} {
	"_id": ObjectId("61c925c4bbdd50138d2b6a7d"),
	"order_id": "3",
	"uid": 30,
	"trade_no": "333",
	"all_price": 145,
	"all_num": 2,
	"items": [{
		"_id": ObjectId("61c924eabbdd50138d2b6a79"),
		"order_id": "3",
		"title": "特仑苏一箱",
		"price": 120,
		"num": 1
	}, {
		"_id": ObjectId("61c92509bbdd50138d2b6a7a"),
		"order_id": "3",
		"title": "吐司面包5个",
		"price": 25,
		"num": 1
	}]
}

(2)示例2:
关联表查询也可以对主表(这里是order集合)进行筛选,排序等操作,$match:{all_price:{$gte:100}}就是筛选价格大于等于100的订单。排序使用{ $sort:{all_price:1}}以此类推。

 db.order.aggregate([ 
 	{ 
 		$lookup: { 
 			from:"order_item", 
 			localField:"order_id", 
 			foreignField:"order_id", 
 			as:"items" 
 		} 
 	},
 	{ 
 		$match:{all_price:{$gte:100}}
 	} 
 ])

在这里插入图片描述

结果:

{
	"_id": ObjectId("61c92596bbdd50138d2b6a7b"),
	"order_id": "1",
	"uid": 10,
	"trade_no": "111",
	"all_price": 10800,
	"all_num": 3,
	"items": [{
		"_id": ObjectId("61c92439bbdd50138d2b6a74"),
		"order_id": "1",
		"title": "Mac电脑1",
		"price": 10000,
		"num": 1
	}, {
		"_id": ObjectId("61c9246ebbdd50138d2b6a75"),
		"order_id": "1",
		"title": "雷蛇鼠标1",
		"price": 300,
		"num": 1
	}, {
		"_id": ObjectId("61c92481bbdd50138d2b6a76"),
		"order_id": "1",
		"title": "转接口1",
		"price": 500,
		"num": 1
	}]
} {
	"_id": ObjectId("61c925c4bbdd50138d2b6a7d"),
	"order_id": "3",
	"uid": 30,
	"trade_no": "333",
	"all_price": 145,
	"all_num": 2,
	"items": [{
		"_id": ObjectId("61c924eabbdd50138d2b6a79"),
		"order_id": "3",
		"title": "特仑苏一箱",
		"price": 120,
		"num": 1
	}, {
		"_id": ObjectId("61c92509bbdd50138d2b6a7a"),
		"order_id": "3",
		"title": "吐司面包5个",
		"price": 25,
		"num": 1
	}]
}

6.2 MongDB数据库的备份和还原

6.2.1 下载database-tools

点击 https://www.mongodb.com/try/download/database-tools 前往下载MongDB的命令行工具。
在这里插入图片描述
之前下载MongoDB的时候安装包安装后bin目录中并不会自带mongodump.exe、mongoexport等工具文件,导致无法执行备份、导出等操作。所以需要自行将下载的database-tools的bin目录中的exe文件复制到MongoDB的bin目录中。否则自行备份等操作时会报错。
在这里插入图片描述

6.2.2 导出 / 备份

重新开个终端

mongodump -h 127.0.0.1 -u admin -p 123456  -d sheldon -o D:\Software\MongoDB\data --authenticationDatabase admin
mongodump -h 数据库ip -u 账号 -p 密码  -d 需要备份的数据库 -o 存放的位置 --authenticationDatabase 用户对应的数据库

-h 数据库ip 用于连接数据库,本地默认是127.0.0.1,因为之前设置了权限,所以也要提供账号密码-u 账号 -p 密码

在这里插入图片描述
备份完毕:
在这里插入图片描述

6.2.3 导入 / 还原

将备份的数据库导入到sheldon1中

mongorestore -h 127.0.0.1 -u admin -p 123456  -d sheldon1  D:\Software\MongoDB\data\sheldon --authenticationDatabase admin
mongorestore -h 数据库ip -u 账号 -p 密码  -d 导入后的数据库名称  备份数据库存放位置 --authenticationDatabase admin

在这里插入图片描述

查看导入的sheldon1数据库。
在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sheldon一蓑烟雨任平生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值