建议直接看NoSql的百度百科,介绍的很详细。这里简单概括下:
NoSQL最常见的解释是“non-relational”, “Not Only SQL”也被很多人接受。NoSQL仅仅是一个概念,泛指非关系型的数据库,区别于关系数据库,它们不保证关系数据的ACID特性。NoSQL是一项全新的数据库革命性运动,其拥护者们提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。
优点:易扩展,NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。无形之间也在架构的层面上带来了可扩展的能力。大数据量,高性能,NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。
MongoDB是NoSql的一种文档型数据库,一个介于关系数据库和非关系数据库之间的产品,是非关系数据库中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似Json的Bjson格式,因此可以存储比较复杂的数据类型。MongoDB最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,还支持为数据建立索引。它的特点是高性能、易部署、易使用、存储数据非常方便。
主要功能特性:
1)面向集合存储,易存储对象类型的数据。
“面向集合”( Collenction-oriented),意思是数据被分组,存储在数据集中,被称为一个集合。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库里的表,不同的是它不需要定义任何模式( Schema)。
2)模式自由。
模式自由,意味着对于存储在Mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。
前往MongoDB官网,选择Community Server
选择对应的版本,点击Download下载
下载后双击安装,过程可以选择自定义目录
安装完成后进行环境配置,找到安装后的MongoDB的bin目录,加入到系统变量的path目录中
打开cmd,输入mongo
查看版本并建立连接,show dbs 查看当前存在的数据库,初始化时有3个内置的数据库,分别是admin、config、local,不要动它们。
注意,每次进行MongoDB操作之前需要先在cmd中执行一次mongo操作建立数据库连接。
mongo
cls可以清空之前的输入和输出内容
cls
show dbs
切换到对应的数据库
use 数据库名称
show collections
db.集合名称.find()
db.集合名称.drop()
db.dropDatabase()
删除数据库前需要使用 use 数据库名称
先切换到该数据库。
db.集合名称.insert({"name":"admin","age":20})
和关系型数据库不同的是,集合(mysql中也叫做表)每次插入的数据字段名称可以不同,值的类型也可以不同。
db.集合名称.find()
find.集合名称.find({"age":22})
db.集合名称.find({"age":{$gt:22}})
db.集合名称.find({"age":{$lt:22}})
db.集合名称.find({"age":{$gte:22}})
db.集合名称.find({"age":{$lte:22}})
db.集合名称.find({"age":{$gte:22,$lte:25}})
db.集合名称.find({name:/zhang/})
db.集合名称.find({name:/^zh/})
db.集合名称.find({name:/i$/})
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,每次查询都会有。
db.集合名称.find({age:{$gt:23}},{name:1,age:1})
升序:
db.集合名称.find().sort({age:1})
降序:
db.集合名称.find().sort({age:1})
db.集合名称.find({name:"zhangsan",age:25})
db.集合名称.find().limit(3)
db.集合名称.find().skip(3)
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
db.集合名称.findOne()
db.集合名称.find({$or:[{age:22},{age:30}]})
db.集合名称.find({age:{$gte:30}}).count()
如果要返回限制之后的记录数量,需要使用count(true)或者count(任何非0数)
db.集合名称.find().skip(3).limit(10).count(true)
删除之前的user集合,重新创建一个admin集合。在MongoDB中可以使用JavaScript批量创建记录,使用for循环,输入
for(vari = 0;i < 100;i++){
回车后,在mongo状态模式中,cmd会判断该语句还处于编辑状态中,继续输入插图插入语句
db.admin.insert("name":"zhangsan"+i,"age":i)
继续回车,直到输入
}
cmd才会认为结束编辑,执行一整条for循环。
db.集合名称.update({"name":"lisi"},{$set:{"age":8}})
把名字叫做lisi的年龄修改为8
db.集合名称.update({"age":8},{$set:{"grade":2}},{multi:true})
{multi:true}
用于批量修改符合条件的记录,如果不加则至修改第一条符合条件的记录。
db.集合名称.update({"name":"zhaosi"},{"name":"zhaozilong","age":7})
替换名字为zhaosi的学生记录为名字改成zhaozilong,年龄改为7
同学们,这一部分可得学好了
db.集合名称.remove({"name":"zhangsan"})
把所有叫做张三的同学都给删除了
db.admin.remove({"age":{$gt:20}})
db.集合名称.remove({"age":7},{justOne:true})
添加索引可以大大优化查询记录的时间。创建user集合,插入60万条数据,用于比较添加索引后的查询时间。
增加索引会大大增加查询效率,但是同时也会让新增和删除操作慢一些
db.集合名称.find({"name":"zhangsan456"}).explain("executionStats")
本次查询名字是zhangsan456的记录所用时间为302毫秒
db.集合名称.getIndexes()
查询出一个对象数组,说明索引可以是多个,默认索引为字段id,即_id,名称为_id_
db.集合名称.createIndex({"name":1})
将name字段作为索引,此时再次查看索引,可以看到新索引的名称为name_1
新增索引之后的查询时间为1毫秒,效率相差了几百倍。因此,当有海量数据需要进行查询时,添加索引必不可少。
db.集合名称.dropIndex({"name":1})
db.集合名称.createIndex({"name":1,"No":1})
添加复合索引后,使用索引中的第一个或者所有条件查询都可以加快查询速度,但是使用第二个条件是是无法为索引提速的。
db.集合名称.find({"name":"zhangsan456","No":456}).explain("executionStats")
db.集合名称.find({"name":"zhangsan456"}).explain("executionStats")
db.集合名称.find({"No":"456"}).explain("executionStats")
使用第二个条件查询,575毫秒,说明复合索引完全无效。相当于使用默认索引的时间。
db.集合名称.createIndex({"name":1},{"unique":true})
先切换到admin集合,添加一条名称相同的记录,再执行添加唯一索引操作,看看会发生什么:
结果是,无法再使用name作为唯一索引,添加name为唯一索引会失败。但是如果将原来的名称重复的记录删除,即可重新添加name为唯一索引:
此时如果再次添加相同名称的记录就会失败:
当然,如果你愿意的话,也可以建立复合索引,只需要保证复合键唯一即可。
切换到MongDB自带的admin数据库
use admin
创建超级管理员
db.createUser({ user:'admin', pwd:'123456', roles:[{role:'root',db:'admin'}] })
查看当前库的用户列表,默认是没有用户的,直到我们添加。
show users
用记事本或者其他编辑器打开MongoDB/bin/mongod.cfg文件,在编辑之前线备份一份,命名为mongod_bac.cfg。
配置安全设置,将#security:替换成
security:
authorization: enabled
重新打开cmd,输入mongo,发现已经没有权限,无法查看。
重新打开cmd,输入
mongo admin -u 用户名 -p 密码
即可进入
切换到某个数据库:
use sheldon
给该数据库添加用户:
db.createUser( { user: "sheldonadmin", pwd: "123456", roles: [ { role: "dbOwner", db: "sheldon" } ] })
mongo sheldon -u sheldonadmin -p 123456
只能看到该数据库
1.数据库用户角色:read、readWrite
2.数据库管理角色:dbAdmin、dbOwner、userAdmin
3.集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
4.备份恢复角色:backup、restore;
5.所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、 dbAdminAnyDatabase
6.超级用户角色:root
const url = 'mongodb://admin:123456@localhost:27017/';
简单来说,就是两个集合A和B,B中最多只有一条记录和A对应。
比如A是身份证信息集合,有身份证id、姓名、性别、名族,B是驾驶证信息集合,有身份证id、驾驶证id,只有一个B的身份证id和A其中的一个身份证id对应,那么这两个集合就是一对一关系。换句话说,一一对应。
简单来说,就是两个集合A和B,B中可以有多条记录和A中的一条记录对应。
比如集合A是人,集合B是游戏账号,一个人可以有多个账号,但是每个账号只能被一个人拥有。
简单来说,就是两个集合A和B,B中可以有多条记录和A中的一条记录对应,A中也可以有多条记录和B中的一条记录对应。
最经典的案例就是一个学生可以选择多门课程,一门课程也可以被多人选择。
在实际项目中用于表的管理查询和数据统计。
先添加3个订单,order是订单表,order_item是订单详情表。用于演示学习。
订单一有3个订单商品,这就是典型的一对多关系。
修改文档的结构,用于重命名、增加或者删除文档中的字段。
db.order.aggregate([
{
$project:{trade_no:1,all_price:1}
}
])
查询order表,只返回trader_no和all_price字段。此时作用和
db.order.find({},{trade_no:1,all_price:1})
db.order.aggregate([
{
$project:{trade_no:1,all_price:1}
},
{
$match:{all_price:{$gte:100}}
}
])
查询订单中总价超过100的订单,并输出trade_no和all_price两个字段。
db.order_item.aggregate([
{
$group:{_id:"$order_id",total:{$sum:"$price"}}
}
])
对order_item表根据order_id字段进行分组,并计算每个分组的总价格。
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}}时就是降序排列)。
db.order.aggregate([
{
$project:{trade_no:1,all_price:1}
},
{
$match:{all_price:{$gte:100}}
},
{
$sort:{all_price:-1}
},
{
$limit:1
}
])
db.order.aggregate([
{
$project:{trade_no:1,all_price:1}
},
{
$match:{all_price:{$gte:100}}
},
{
$sort:{all_price:-1}
},
{
$skip:1
}
])
(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
}]
}
点击 https://www.mongodb.com/try/download/database-tools 前往下载MongDB的命令行工具。
之前下载MongoDB的时候安装包安装后bin目录中并不会自带mongodump.exe、mongoexport等工具文件,导致无法执行备份、导出等操作。所以需要自行将下载的database-tools的bin目录中的exe文件复制到MongoDB的bin目录中。否则自行备份等操作时会报错。
重新开个终端
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 密码
将备份的数据库导入到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