简介
MongoDB 基于分布式文件存储的数据库
相较于用 db.json 纯文件管理数据,用数据库管理数据速度更快、扩展性高、安全性高
MongoDB的操作语法与JS相似
核心概念:
- 数据库(database) 数据库是一个数据仓库,数据库服务下可以创建很多数据库,数据库中可以存
放很多集合 - 集合(collection) 集合类似于 JS 中的数组,在集合中可以存放很多文档,一个集合存放一种文档(字段类型相同的文档)
- 文档(document) 文档是数据库中的最小单位,类似于 JS 中的对象,一个文档中有许多字段(对象的属性)
命令行交互
在将bin文件夹添加至环境变量后,在终端中输入 mongod 启动服务端,mongo 启动客户端
1、数据库命令
1 | // 显示所有的数据库 |
2、集合命令
1 | // 创建集合 |
3、文档命令
1 | // 插入文档 |
Mongoose
Mongoose 是一个对象文档模型库,在异步环境中工作,用代码操作 mongodb 数据库
连接数据库:
1 | const mongoose = require('mongoose'); |
常用方法:
1、创建文档模型对象:
mongoose.Schema()
创建文档的结构对象,约束文档字段的数据类型mongoose.model(<集合名称>, <结构对象>)
创建模型对象,对文档操作的封装对象,集合有则使用无则自动创建,集合名称会自动变为复数
2、插入、增加文档:
create())
创建并插入一个新文档insertMany()
传入文档数组批量添加新文档
3、删除文档:
deleteOne()
删除一条文档deleteMany()
批量删除
4、更新文档:
updateOne()
更新一条文档updateMany()
批量更新
5、查找、读取文档:
findOne()
查找一条findById()
通过_id找一条find()
批量查找,无论找到多少条都返回数组
6、条件控制:
- >
$gt
- <
$lt
- >=
$gte
- <=
$lte
- !==
$ne
- ||
$or
也可以用 || - &&
$and
也可以用 && - 正则匹配
{author: /鱼/}
7、规则控制:
select()
字段筛选sort()
排序skip()
数据截取,跳过limit()
数据截取,限定
插入文档
插入新文档流程:在open事件的回调函数中操作
mongoose.Schema()
创建文档的结构对象,约束文档字段的数据类型mongoose.model(<集合名称>, <结构对象>)
创建模型对象,对文档操作的封装对象,集合有则使用无则自动创建,集合名称会自动变为复数模型对象.create({文档数据对象}).then(data=>{})
创建新文档
1 | // 在open事件的回调函数中操作 |
批量插入文档
create() 一次只能新增一个文档,使用 insertMany()
传入文档数组批量添加新文档
1 | mongoose.connection.once('open', () => { |
字段
文档结构可选的常用字段类型:
- String 字符串
- Number 数字
- Boolean 布尔值
- Array 数组,也可以使用 [] 来标识
- Date 日期
- Buffer Buffer 对象
- Mixed 任意类型,需要使用 mongoose.Schema.Types.Mixed 指定
- ObjectId 文档对象 ID,用于设置外键,保存其它文档的id,需要使用 mongoose.Schema.Types.ObjectId 指定
- Decimal128 高精度数字,需要使用 mongoose.Schema.Types.Decimal128 指定
字段值验证:一些内建验证器,可以对字段值进行验证,或者说进一步约束字段内容
- required: true 设置必填项
- default: ‘qx’ 设置默认值
- enum: [‘男’,’女’] 枚举值,字段值必须在数组中
- unique: true 设置值唯一,需要重建集合才有效果
在创建文档的结构对象时添加字段验证
1 | let BookSchema = mongoose.Schema({ |
删除文档
deleteOne()
删除一条文档,deleteMany()
批量删除
1 | // 删除单条文档 |
更新文档
updateOne()
和 updateMany()
1 | // 更新单条 |
查找文档
findOne()
查找一条,findById()
通过_id找一条,find()
批量查找,无论找到多少条都返回数组
1 | // 读取单条 |
条件控制
mongodb中没有条件运算符,必须使用替代符号
- >
$gt
- <
$lt
- >=
$gte
- <=
$lte
- !==
$ne
- ||
$or
也可以用 || - &&
$and
也可以用 &&
1 | // 价格高于20 |
正则匹配:条件中可以直接使用 JS 的正则语法,通过正则可以进行模糊查询
1 | // 搜索作者名带鱼写的书 |
规则控制
1、字段筛选 select()
查找时只查找文档的某些字段,提高查找效率,1 需要,0 排除,_id默认为1
1 | BookModel.find({price: { $lt: 30 }}).select({name:1,author:1,price:1}) |
2、排序 sort()
,按某个字段的升序(1)或降序(-1)排序
1 | BookModel.find().sort({price:1}).select({name:1,author:1,price:1}) |
3、数据截取,skip()
跳过,limit()
限定
1 | BookModel.find().sort({price:-1}).select({name:1,price:1}).limit(3) |
1 | BookModel.find().sort({price:-1}).select({name:1,price:1}).skip(3) |
代码模块化
mongoose的模块化:
- 将数据库连接部分独立,并放入一个函数中暴露出去
- 将数据库中不同的文档对象模型每个单独一个js文件独立到modules文件夹中,将文档对象模型暴露出去
- 将数据库的连接信息独立到config.js再暴露出去给db.js使用
- index.js导入数据库连接函数和文档对象模型,并将连接数据库成功后的操作,都放在数据库连接函数的第一个参数中,作为连接成功的回调函数
1 | const mongoose = require('mongoose'); |
模块化后:
作用:当需要对数据库中一个集合操作时,只需要在models文件夹中新建该集合的文档对象模型,然后在index.js中导入,当要连接其它mongodb数据库时也只需要修改config.js
1 | const mongoose = require('mongoose'); |
1 | const config = { |
1 | // 暴露一个函数,success数据库连接成功的回调,error连接失败的回调 |
1 | const mongoose = require('mongoose'); |
图形化管理
使用图形化软件更方便操控数据库 Robo3T Navicat
记账本优化
使用 mongodb 数据库替代 lowdb 文件管理,使用 moment 处理日期类型
主要文件:
数据库相关:
1 | // 暴露一个函数,success数据库连接成功的回调,error连接失败的回调 |
1 | const mongoose = require('mongoose'); |
1 | const config = { |
启动http服务的www文件:导入数据库连接函数,将http服务的代码都扔进db的回调函数中,待数据库连接成功再执行回调函数运行http服务
1 |
|
路由相关:index.js内有增删该查的页面、接口路由,在这个文件中引入文档对象模型,就能在对应路由内对数据库文档做对应操作
1 | var express = require('express'); |
除了index.ejs,其它页面无变化
1 | <div class="date"><%= moment(item.date).format('YYYY-MM-DD') %></div> |