- 2021-11-30
- 13-1 本章主要内容
- 13-2 MongoDB 是文档数据库
- 2021-12-1
- 13-3 MongoDB安装 - 介绍
- 13-4 安装MongoDB-mac-安装homebrew
- 13-5 安装MongoDB-mac-安装MongoDB
- 13-6 安装MongoDB-mac-安装Compass
- 13-10 用 compass 操作 mongodb
- 2021-12-2
- 13-11 用命令行操作mongodb
- 13-12 mongodb的几个重要概念
- 13-13 nodejs连接mongodb-part1
- 2021-12-3
- 13-14 nodejs操作mongodb-part2
- 2021-12-4
- 13-15 使用mongoose连接mongodb服务
- 13-16 mongoose的Schema和Model
- 2021-12-5
- 13-18 mongoose操作mongodb
- 13-19 博客项目web-server链接mongodb服务端
- 13-20 博客项目web-server使用mognodb数据库
- 2021-12-5
- 13-21 博客项目web-server使用mongodb-联调和测试
- 13-22 本章总结
2021-11-30
13-1 本章主要内容
使用 MongoDB
- 之前一直使用 mysql 数据库
- MongoDB 也是 Nodejs 常用数据库
- 两者有何区别?该怎么应用?
不要被误导!
- MongoDB 和 MySQL 是不同的数据库,有不同的使用场景
- 并不是 MongoDB 适合 nodejs,而 mysql 不适合 nodejs
- 网上很多用 MongoDB,完全是因为 MongoDB 使用简单
本章内容
- MongoDB 介绍
- MongoDB 安装和启动
- MongoDB 的基本使用
- MongoDB 重要概念
- nodejs 连接 MongoDB
- Mongoose 项目重构
13-2 MongoDB 是文档数据库
MongoDB 介绍
- MongoDB 是一个文档数据库
- MongoDB 和 MySQL Redis 的对比
- 如何选择?举例说明
文档数据库
- mysql 以表格形式存储数据
- Redis 以 key/value 形式来存储数据
- MongoDB 以文档形式存储数据,格式像 JSON
表格 vs 文档
- 先不用管 mysql 和 MongoDB,后面再讨论
- 先思考一下,哪些适合用表格,哪些适合用文档?
- 即,哪些适合用 Excel写,哪些适合用 Word 写
- Excel适合存储格式规整的信息,如员工打卡记录,工资表
- Word适合存储格式松散的信息,如需求文档、宣传方案
MongoDB 对比 MySQL redis
- mysql - 关系型,表格存储,SQL操作,硬盘
- Redis - 非关系型,key-value 存储,NoSQL,内存
- MongoDB - 非关系型,文档存储,NoSQL,硬盘
- Excel 可类比 MySQL,Word 可类比 MongoDB
- MySQL 适合存储格式规整的信息
- MongoDB 适合存储格式松散的信息,两者可以同时使用
两者结合使用的例子
网页信息是非常不规整的,所以网页内容可以存储到 MongoDB 中去
博客项目 - 和搜索爬虫类似
- 用户表,适合用 MySQL 存储
- 博客记录,适合用 MySQL 存储
- 博客的内容,适合用MongoDB 存储
2021-12-1
13-3 MongoDB安装 - 介绍
MongoDB 安装
- 安装 MongoDB 服务端 (Windows 和 mac)
- 安装 MongoDB 客户端 (Windows 和 mac)
- 启动和连接
13-4 安装MongoDB-mac-安装homebrew
mac 安装 MongoDB
- 安装 homebrew
- 用 homebrew 安装 MongoDB
- 安装客户端 compass
1.安装 homebrew https://brew.sh/index_zh-cn
2.切换源
https://www.jianshu.com/p/bea984d27cd2
13-5 安装MongoDB-mac-安装MongoDB
在 github 中搜索 mongodb/homebrew-brew
https://github.com/mongodb/homebrew-brew
安装社区版本(MongoDB 不开源)
先切换为独立版本
brew tap mongodb/brew
brew install mongodb-community
慢慢下吧
下好了
类似
https://www.jianshu.com/p/97ae53b089f5
13-6 安装MongoDB-mac-安装Compass
https://www.mongodb.com/try/download/compass
下载
然后在启动台里面找到 compass 启动
然后进入,在启动好 MongoDB 的情况下点击 connect 连接 compass
13-10 用 compass 操作 mongodb
MongoDB 使用
- 创建一个数据库(database)
- 创建集合(collection)
- 文档(document)的增删改查
为了更好的管理文档
- MongoDB 是一个文档数据库,以文档存储信息
- 但文档也不能散着,否则多了不好管理
- 分三层管理:数据库->集合->文档
和 MySQL 对比
- MongoDB 数据库 - MySQL数据库
- MongoDB 集合 - MySQL 表
- MongoDB 文档 - MySQL记录(一行数据)
使用 compass 来演示
点左下方的 + 号 创建数据库
然后创建两个 collection :users 和 blogs
然后在 users 这个 collection 中创建一条数据(点击 add data)
可以把这个_id 想象为一个主键,保证数据的唯一性
2021-12-2
13-11 用命令行操作mongodb
命令行操作
在一些没有桌面的系统必须要用控制台来操作,控制台必学
- 展示数据库:show dbs
- 新建: use myblog1
- 进入:依然是 use ,
- 展示集合:show collections
- 向某个集合中插入数据:
- db.blogs.insert({“title”: “标题1”, “content”: “内容1”, “author”: “zhangsan”})
- db 表示当前的数据库,然后通过 点 来调用
- 返回:WriteResult({ “nInserted” : 1 }) 说明成功插入一个文档
- 查询文档:
- db.blogs.find()
- find中可以加查询条件
- 对查找的内容进行排序
- db.blogs.find().sort({ _id: -1 })
- 对 _id 进行倒序排序
- 更新文档:
- db.blogs.update(更新条件-更新哪个,更新后的内容)
- db.blogs.update({“author”: “zhangsan”},{$set: {“title”: “标题A”}})
- 删除文档:
- db.blogs.remove()
- remove 中加条件
总结
- 数据库(database)创建集合(collection)文档(document)
- 使用 compass 操作
- 使用命令行操作
13-12 mongodb的几个重要概念
MongoDB 概念
- 数据库
- 集合
- 文档
- bson
- NoSQL
数据库database
- MongoDB 可以成为数据库系统(服务)
- 服务层级的,不是功能层级的
- 一个数据库系统,允许对接很多服务
- 每个服务,就对接一个(或多个)数据库
集合 collection
- 数据库是一个服务(业务)的数据容器
- 一个服务(业务)的数据,要分类管理
- 如博客系统,有博客数据,有用户数据
文档 document
- 集合 collection 也是一个数据容器
- 相对数据库而言
- 文档 document 是单条数据,如一条博客,一个用户
- 可以被增删改查
bson
- JSON 是一种常用的数据格式
- JSON 是字符串类型的
- BSON = Binary JSON 即二进制类型的JSON
因此 MongoDB 不是用 JSON 来存储的,而是用类似于 JSON 的 BSON 来存储的
NoSQL
- 关系型数据库(如 mysql)需要学习 SQL 语言
- 如 select content
- NoSQL 数据库则无需用 SQL 语句进行查询,易学易用
13-13 nodejs连接mongodb-part1
连接
- 安装 MongoDB npm 插件
- 连接数据库,连接集合
- 操作文档,CRUD
新建一个 mongodb-test
然后 npm init -y
安装 MongoDB 这个依赖 npm i mongodb
然后新建如下目录和文件
const MongoClient = require('mongodb').MongoClient
// 设置地址
const url = 'mongodb://localhost:27017'
// 数据库的名字
const dbName = 'myblog'
MongoClient.connect(
url,
{
// 配置
},
(err, client) => {
if (err) {
console.error('mongodb connect error', err)
return
}
// 没有报错,说明连接成功
console.log('mongodb connect success')
// 切换到数据库 (use myblog)
const db = client.db(dbName)
// 关闭连接
// 正式项目不关连接
client.close()
}
)
2021-12-3
13-14 nodejs操作mongodb-part2
操作增删改查
查询
中间因为是异步,所以需要把关闭连接放到异步回调里
// 切换到数据库 (use myblog)
const db = client.db(dbName)
// 数据库 -> 集合(blogs users) -> 文档
// 使用集合
const usersCollection = db.collection('users')
// 查询数据
usersCollection.find().toArray((err, result) => {
if (err) {
console.error('users find error', err)
return
}
console.log(result)
// 关闭连接
// 正式项目不关连接
client.close()
})
新增
// 新增数据
usersCollection.insertOne({
username: 'demonlb',
password: 'abc',
realname: '肉饼'
}, (err, result) => {
if (err) {
console.error('users insert error', err)
return
}
console.log(result)
client.close()
})
修改
// 修改数据
usersCollection.updateOne(
{ username: 'lisi' }, // 查询条件
{ $set: { realname: '李四' } }, // 修改内容,注意有 $set
(err, result) => {
if (err) {
console.error('users update error', err)
return
}
console.log(result)
client.close()
}
)
删除
// 删除数据
usersCollection.deleteOne(
{a: 101},
(err, result => {
if (err) {
console.error('users delete error', err)
return
}
console.log(result === 'undefined')
client.close()
})
)
如果返回 undefined 代表删除成功
总结
- 安装 mongodb npm 插件
- 连接数据库,连接集合
- 操作数据库,CRUD
2021-12-4
13-15 使用mongoose连接mongodb服务
mongoose
在 MongoDB 的层级之上
- Schema 和 Model(规范和模型)
- 基于 Model 操作数据
- 使用 MongoDB 重构项目
MongoDB 数据格式过于灵活
- 可以插入任何格式数据,不受限制
- 实际项目开发时,要有数据格式的规范(重要)
- 特别是多人协作开发时
那不就和 MySQL 一样了吗?
- 这仅仅是使用层面的调整,并不是MongoDB 的初衷
- 如果数据格式以松散数据为主,少量格式规范的数据,可以这么用(mongoose)
- 如果大量数据都是规范数据,最好直接选择 MySQL
mongoose 可提供规范
- Schema 定义数据格式的规范
- 以 Model 规范 collection
- 规范数据操作 API
实操
安装 mongoose
npm i mongoose —save
然后新建 mongoose 文件夹进行测试
连接一下
const mongoose = require('mongoose')
const url = 'mongodb://localhost:27017'
const dbName = 'myblog'
mongoose.connect(`${url}/${dbName}`, {
// 配置信息
})
// 获取连接对象
const db = mongoose.connection
// 处理连接错误报错
db.on('error', err => {
console.error(err)
})
// 连接成功 open 状态
db.once('open', () => {
console.log('mongoose connect success')
})
module.exports = mongoose
13-16 mongoose的Schema和Model
新建一个 models 的文件夹
然后再依次新建两个文件 Blog.js 和 User.js
然后写规范和model
// 对应 blogs 的那个 collection
const mongoose = require('../connect')
// 用 Schema 定义数据规范
// 和 collection 里面数据一一对应,key: type
const BlogSchema = mongoose.Schema({
title: {
type: String,
required: true, // 必需
},
content: String,
author: {
type: String,
required: true, // 必需
},
})
// Model 对应 collection
// 这里把 collection 名字特地写成单数形式,mongoose 会在对应时自动将其变为复数形式
const Blog = mongoose.model('blog', BlogSchema)
module.exports = Blog
类似的
// 对应 users 的那个 collection
const mongoose = require('../connect')
// 用 Schema 定义数据规范
// 和 collection 里面数据一一对应,key: type
const UserSchema = mongoose.Schema({
username: {
type: String,
required: true, // 必需
unique: true // 唯一,不能重复
},
password: String,
realname: String
})
// Model 对应 collection
// 这里把 collection 名字特地写成单数形式,mongoose 会在对应时自动将其变为复数形式
const User = mongoose.model('user', UserSchema)
module.exports = User
2021-12-5
13-18 mongoose操作mongodb
操作用户表
const User = require('../models/User')
// 自执行的异步函数
!(async () => {
// 创建用户
const zhangsan = await User.create({
username: 'zhangsan',
password: '123',
realname: '张三'
})
console.log('zhangsan', zhangsan)
})()
插入成功!
然后查询
// 查询
const list = await User.find()
console.log(list)
操作博客表
类似的
const Blog = require('../models/Blog')
// 自执行的异步函数
!(async () => {
// 新建博客
const blogCreate = await Blog.create({
title: 'mongoose标题',
content: 'mongoose内容',
author: 'demonlb'
})
console.log('blogCreate', blogCreate)
})()
全部
const Blog = require('../models/Blog')
// 自执行的异步函数
!(async () => {
// 新建博客
const blogCreate = await Blog.create({
title: 'mongoose标题',
content: 'mongoose内容',
author: 'demonlb'
})
console.log('blogCreate', blogCreate)
// 获取列表,按照 id 逆序排列
const list = await Blog.find().sort({ _id: -1 })
console.log('list', list) // 数组形式
// 模糊查询 /标题/ /A/
// 根据 id 获取博客内容获取的是对象形式的内容
const blogGetById = await Blog.findById('61ac1d62ea6da95064e180c9')
console.log('blogGetById', blogGetById)
// 修改博客
const blogUpdate = await Blog.findOneAndUpdate(
{ _id: '61ac1d62ea6da95064e180c9' },
{ content: 'mongoose 修改后的内容' },
{
new: true // 返回修改后的内容,默认为 false,即返回修改前的内容
}
)
console.log('blogUpdate', blogUpdate)
// 删除博客
const blogDelete = await Blog.findOneAndDelete({
_id: '61ac1d62ea6da95064e180c9',
author: 'demonlb' // 验证一下作者,增加安全性,防止误删
})
console.log('blogDelete', blogDelete)
})()
13-19 博客项目web-server链接mongodb服务端
使用 mongodb 重构项目
- 回顾现有代码(基于 koa2 编写的)
- 定义 Schema 和 Model
- 完善数据操作
先把之前使用 mysql-koa2 的项目内容复制到新创建的 blog-koa2-mongodb ,然后重构
首先安装 mongoose
然后复制 models 文件夹和 db.js 到 db文件夹中,
然后给 models 里的 Schema 加一个时间戳 (timestamps)
然后下一步就开始改 controller 代码
13-20 博客项目web-server使用mognodb数据库
修改 controller-user.js
首先修改 controller/user.js
const User = require('../db/models/User')
const { genPassword } = require('../utils/crypt')
const login = async (username, password) =>{
// 生成加密密码
password = genPassword(password)
const userList = await User.find({
username,
password
})
if (userList.length === 0) return {}
return userList[0]
}
module.exports = {
login
}
更新加密密码
因为这里的密码是加密过的,所以要将数据库中的密码也修改成加密过的
新建一个 password_test.js 然后把 genPassword 引入进来 将数据库里的账号和密码都进行解析,变成加密过的
依次更新一下
修改 controller-blog.js
类似的
const xss = require('xss')
const Blog = require('../db/models/Blog')
const getList = async (author, keyword) => {
// 动态拼接查询条件
const whereOpt = {}
if (author) whereOpt.author = author
// 兼容模糊查询
if (keyword) whereOpt.keyword = new RegExp(keyword)
const list = await Blog.find(whereOpt).sort({ _id: -1 })
return list
}
const getDetail = async (id) => {
const blog = await Blog.findById(id)
// 创建时间格式化
return blog
}
const newBlog = async (blogData = {}) => {
// blogData 是一个博客对象,包含 title content author属性
const title = xss(blogData.title)
const content = xss(blogData.content)
const author = blogData.author
const blog = await Blog.create({
title,
content,
author
})
return {
id: blog._id
}
}
const updateBlog = async (id, blogData = {}) => {
// blogData 是一个博客对象,包含 title content 属性
// 更新时只需要更新blogData的 title content 属性
const title = xss(blogData.title)
const content = xss(blogData.content)
const blog = await Blog.findOneAndUpdate(
{ _id: id },
{ content, title },
{ new: true}
)
if (blog == null) return false
return true
}
const deleteBlog = async (id, author) => {
// id 就是要删除博客的id
const blog = await Blog.findOneAndDelete(
{ id: _id, author },
)
if (blog == null) return false
return true
}
module.exports = {
getList,
getDetail,
newBlog,
updateBlog,
deleteBlog
}
2021-12-5
13-21 博客项目web-server使用mongodb-联调和测试
然后 npm run dev 启动一下项目
测试一下,没什么问题
13-22 本章总结
本章主要是把项目切换到 MongoDB 的数据库,也就说是项目的第三次重构
本章内容
- MongoDB 介绍
- MongoDB 的安装和启动-Windows Mac
- MongoDB 的基本使用-compass terminal
- MongoDB 的重要概念-数据库, 集合,文档,bson,NoSQL
- nodejs 连接 MongoDB
- mongoose 项目重构 - Schema model