简介

MongoDB为面向文档(基于分布式文件存储)数据库(非关系型数据库)

非关系型数据库的结构:一台服务器 => 数据库 => 集合 => 文档

非关系型数据库用于超大规模数据的存储

面向文档数据库会将数据以文档形式存储。每个文档都是自包含的数据单元,是一系列数据项的集合。
每个数据项都有一个名词与对应值,值既可以是简单的数据类型,如字符串、数字和日期等;也可以是复杂的类型,如有序列表和关联对象。
数据存储的最小单位是文档,同一个表中存储的文档属性可以是不同的,数据可以使用XML、JSON或JSONB等多种形式存储

优点:
高性能,易部署,易使用,存储数据方便
面向集合存储,易存储对象类型的数据
模式自由
支持动态查询
支持完全索引,包含内部对象
支持查询
支持复制和故障恢复
使用高效的二进制数据存储,包括大型对象(如视频)
自动处理碎片,以支持云计算层次的扩展性
支持ruby,python,java,c++,php等多种语言
文件存储格式为BSON(一种JSON的扩展),可直接存储对象,数组

部分应用场景:
视频直播:使用MongoDB存储点赞,评论,弹幕信息...
游戏场景:使用MongoDB存储打怪记录,用户积分...
社交场景:使用MongoDB存储朋友圈信息,浏览记录...
电商场景:使用MongoDB存储购物车,收藏...

官网:https://www.mongodb.com/

MongoDB的安装

下载安装地址:https://www.mongodb.com/try/download
windows详细安装与配置教程可查看网址:

MongoDB的可视化工具

RoBo3T是MongoDB的可视化界面管理工具
下载安装地址:https://robomongo.org/download
详细安装与配置教程可查看网址:

MongoDB的文件目录说明

mongodb 数字为科学计数 mongodb数据基本单位_mongodb

将MongoDB安装成window服务

先在非系统盘下创建一个文件夹mongodb,再创建两个子文件夹db和log

使用命令挂载服务:
在cmd中输入命令:mongod --dbpath "G:\mongodb\db"(db的路径)--logpath "G:\mongodb\log\mongodb.log"(log文件夹的路径,自动创建一个mongodb.log文件)--install --serviceName "MongoDB"(服务名称)

查看服务:
我的电脑 -> 右键 -> 管理 -> 服务与应用程序 -> 服务

使用这些命令的前提是已挂载到windows服务上
开启服务的命令:net start mongodb(服务名)
关闭服务的命令:net stop mongodb(服务名)
卸载服务的命令:sc delete mongodb(服务名)

没有挂载服务的话,可直接在cmd中进入mongodb的bin目录下,输入命令:mongod --dbpath= G:\mongodb\data(data的路径)来开启服务

MongoDB常用命令

进入数据库管理模式:mongo
在数据库管理模式中只能执行数据库命令,不能执行其他命令

mongodb 数字为科学计数 mongodb数据基本单位_mongodb_02

退出数据库管理模式:exit

常用的数据库命令:
1. 显示所有的数据库列表:show dbs
2. 创建数据库:use 数据库名 (若数据库名不存在则创建,若已存在则进入)
3. 查看当前数据库是哪个:db
4. 删除数据库:db.dropDatabase()

关于集合的命令: 
1. 显示当前数据库的所有集合:show collections
2. 创建集合:db.集合名.insert({}) (通常在创建数据时自动创建集合,不需要单独创建)
            db.createCollections(集合名)
3. 删除集合:db.集合名.drop()

关于文档(数据)的操作:
1. 新增文档(数据):db.集合名.insert({BSON数据}) (向集合中插入一条数据)(推荐使用)
                    db.集合名.save({BSON数据}) (向集合中插入一条数据,若集合中已经存在该数据则更新)(该方法新版本已弃用,可使用db.集合名.insertOne()或db.集合名.replaceOne())
                    db.集合名.insertOne({BSON数据}) 
2. 查看文档(数据):db.集合名.find() (查找当前集合中的所有数据,是个数组)
                    db.集合名.find({条件对象}) (查找符合条件的文档(数据))
                    db.集合名.findOne() (查找当前集合中的第一条数据)
                    db.集合名.find().pretty() (将找到的数据以格式化的结果显示出来)
3. 修改文档(数据):db.集合名.update(查找的对象,修改结果)
                    db.集合名.update({修改1},{修改2},{multi:true}) ({multi:true}表示能更新多条数据)
                    db.集合名.update({条件},{$inc:{key:value}}) ($inc实现对某列的值进行自增操作)
4. 删除文档(数据):db.集合名.remove({}) ({}为空则删除当前集合中的所有数据,{}有值则删除符合对应条件的数据)
(由于删除和更新操作数据会造成极大影响,所以要谨慎!)

一些高级命令:
1. 按指定条件查询:db.集合名.find({key:value})
2. 按大于某个范围的条件查询:db.集合名.find({key:{$gt:value}}) (key>value)
3. 按大于等于某个范围的条件查询:db.集合名.find({key:{$gte:value}}) (key>=value)
4. 按小于某个范围的条件查询:db.集合名.find({key:{$lt:value}}) (key<value)
5. 按小于等于某个范围的条件查询:db.集合名.find({key:{$lte:value}}) (key<=value)
6. 查询指定范围的数据:db.集合名.find({key:{$gt:value1,$lt:value2}})
7. 查询指定的数据是否在数组中:db.集合名.find({key:{$in:[...]}})
8. 按数组元素的个数查找:db.集合名.find({key:{$size:数量}})
9. 查找多个条件中符合其中一个条件的数据:db.集合名.find({$or:[{key1:value1},{key2:value2},...}]})
10. 查找同时符合多个条件的数据:db.集合名.find({key1:value1,key2:value2})
11. 排序:db.集合名.find().sort({key1:1/-1,key2:1/-1}) (1代表升序,-1代表降序)
12. 限定输出数据的条数.limit(Number),跳过指定的数据条数.skip(Number) (配合使用,一般用作分页功能)
    返回集合的条数:db.集合名.find().count()
e.g. 现在有100条数据,每页显示10条,一共有多少页?(10页)
     若当前在第2页上,应显示哪些数据?(11-20之间的数据(即跳过前10条))
13. 模糊查询:db.集合名.find({key:/相应的reg/}) (可用于查找某姓之人或含某些关键字的)

MongoDB—聚合函数

MongoDB中聚合主要用于处理数据(如:统计平均值,求和等),并返回计算后的数据结果

聚合的方法使用aggregate()
基本的语法格式:
db.集合名.aggregate([
    {
        管道:(聚合操作表达式)
    }
])

管道:把聚合操作表达式找到的数据进行过滤

mongodb 数字为科学计数 mongodb数据基本单位_数据_03

mongodb 数字为科学计数 mongodb数据基本单位_数据库_04

mongodb 数字为科学计数 mongodb数据基本单位_数据库_05

常用的聚合表达式:
$sum:计算总和({$sum:1}相当于count(*)计算全部)
$avg:计算平均值
$min:获取集合中所有文档对应值的最小值
$max:获取集合中所有文档对应值的最大值

例子:

mongodb 数字为科学计数 mongodb数据基本单位_数据_06

MongoDB的安全认证(了解)

查询所有角色权限(仅含用户自定义角色):db.runCommand({rolesInfo:1})
查询所有角色权限(包含内置角色的所有角色):db.runCommand({rolesInfo:1,showBuiltinRoles:true})
查询其它数据库中指定的角色权限:db.runCommand({rolesInfo:{role:角色名,db:数据库名}})
查询多个角色权限:db.runCommand({rolesInfo:[角色名...,{role:角色名,db:数据库名}]})
常见的角色:

mongodb 数字为科学计数 mongodb数据基本单位_数据库_07

添加用户和权限:
进入数据库后

mongodb 数字为科学计数 mongodb数据基本单位_数据库_08

认证测试:
切换到admin数据库中,输入命令:db.auth('账号','密码')

创建普通用户:

mongodb 数字为科学计数 mongodb数据基本单位_数据库_09

开启认证:

mongodb 数字为科学计数 mongodb数据基本单位_数据_10

mongodb 数字为科学计数 mongodb数据基本单位_数据库_11

MongoDB—索引

索引分类:
单字段索引,复合索引,地理空间索引,文本索引,哈希索引,...

全文检索:

mongodb 数字为科学计数 mongodb数据基本单位_mongodb_12

启用全文检索:

mongodb 数字为科学计数 mongodb数据基本单位_数据库_13

创建索引:db.集合名.createIndex(keys,options)
options的配置:background(布尔类型,默认为false,指定是否后台创建索引。在创建索引过程中会阻塞数据库的其他操作,而后台创建就会避免这种问题)
               unique(布尔类型,默认为false,指定建立的索引是否唯一) 
               name(索引名称,默认通过建立索引的字段名和排序顺序生成索引名称) 

删除索引:db.集合名.dropIndex(索引名称或索引键值对)

查看索引:db.集合名.getIndexes() (返回一个集合中的所有索引)

查看集合索引大小:db.集合名.totalIndexSize()

利用查询分析可确保建立的索引是否有效:

mongodb 数字为科学计数 mongodb数据基本单位_mongodb 数字为科学计数_14

MongoDB—数据库备份与恢复

备份:使用mongodump命令(可导出所有数据到指定目录中,还可通过参数指定导出的数据量级转存的服务器)
mongodump命令语法:

mongodb 数字为科学计数 mongodb数据基本单位_mongodb_15

mongodb 数字为科学计数 mongodb数据基本单位_数据_16

mongodb 数字为科学计数 mongodb数据基本单位_mongodb 数字为科学计数_17

恢复:使用mongorestore命令
mongorestore命令语法:

mongodb 数字为科学计数 mongodb数据基本单位_mongodb_18

mongodb 数字为科学计数 mongodb数据基本单位_mongodb_19

mongoose模块

node.js利用mongoose模块来操作MongoDB,是一种便捷的封装,一种对象模型工具  

mongoose官网:http://www.mongoosejs.net/

安装mongoose:
npm install mongoose (安装前提是要先安装express框架)

引入mongoose模块:
var mongoose = require('mongoose');

连接数据库:mongoose.connect('mongodb://127.0.0.1:27017/数据库名(服务器地址)',(err)=>{...(有错误则throw err)}) (MongoDB的默认端口号为:27017)
(在routers目录下的index.js中编写连接数据库的命令)

骨架Schema:
一种以文件形式存储的数据库模型骨架,不具备数据库操作能力
不仅定义了文档结构和使用性能还可以扩展插件,实例方法,复合索引,文档生命周期钩子
Model:由Schema发布生成的模型,具有抽象属性和行为的数据库操作的能力,通常用于读取数据库(查)
Entity:由Model创建的实体,其操作也会影响数据库,通常用于写数据(增删改)

连接数据库后,存储数据的步骤:定义骨架(Schema)-> 创建模型(Model)-> Entity实例化方法

定义骨架:
var schema=new mongoose.Schema({
    字段名:类型,(类型:String,Number,Date,Buffer,ObjectId,Array,Boolean,...)(若骨架没有定义属性及类型,是不能被加进数据库的)
    ...
})

创建模型:
var model=mongoose.model(模型名,骨架名,集合名称(与模型名保持一致))
创建好model后,就可以使用相应的方法:
根据条件进行数据查询,可以找出多条数据:model.find({条件},(err,data)=>{...(data是从数据库中读取到的数据)}) (find找出来的数据一定是一个数组)
根据id查找一条数据:model.findById('id',(err,data)=>{..,}) (findById找出来的数据是一个对象)
另一种常用写法:model.find({}).limit().exec((err,data)=>{...})  (好处是可实现链式调用)

创建实体Entity(依赖于Model):
var 实体名=new 对应的模型();
新增数据:
实体名.属性名=属性值;
实体名.save(()=>{});  (将添加到实体上的属性保存到数据库中)
删除数据:
先找出要删除的数据,再调用remove()方法删除数据:实体名.remove(()=>{}); 
如:model.findById(id).exec((err,data)=>{data.remove(err)=>{...}})
修改数据:
先找出要修改的数据,将数据修改后保存回数据库
如:model.findById(id).exec((err,data)=>{data.name=新值;data.save(()=>{...}))})