一、简介
1、MongoDB 是什么
MongoDB 是一个基于分布式文件存储的数据库,官方地址 https://www.mongodb.com/
2、数据看是什么
数据库(DataBase)是按照数据结构来组织、存储和管理数据的应用程序。
3、数据库的作用
主要作用是 管理数据,对数据进行 增(c)、删(d)、改(u)、查(r)
4、数据库管理数据的特点
- 速度更快
- 扩展性更强
- 安全性更强
5、为什么选择 MongoDB
操作语法与 JavaScript 类似,容易上手,学习成本低
二、核心概念
- 数据库(database):是一个数据仓库,数据库服务下可以创建很多数据库,数据库可以存放很多集合(类似于js中的数组)
- 集合(collection):类似于 JS 中的数组,在集合中可以存放很多文档
- 文档(document):是数据库中的最小单位,类似于js中的对象
JSON 文件示例:
{ "accounts": [ { "id": "3-YLju5f3", "title": "买电脑", "time": "2023-02-08", "type": "-1", "account": "5500", "remarks": "为了上网课" },{ "id": "3-YLju5f4", "title": "请女朋友吃饭", "time": "2023-02-08", "type": "-1", "account": "214", "remarks": "情人节聚餐" },],"users":[ { "id": 1, "name": "zhangsan","age": 18 },{ "id": 2, "name": "lisi", "age": 20 },{ "id": 3, "name": "wangwu", "age": 22 } ]
}
上面 json 文件中:
- 一个 json 文件好比是一个 数据库,一个 MongoDB 服务下可以有 n 个数据库
- json 文件中的 一级属性的数据值 好比是 集合(accounts、users)
- 数组中的对象好比是 文档
- 对象中的属性有时也称为字段
一般情况下:
- 一个项目使用 一个数据库
- 一个集合会存储同一种类型的数据
三、下载安装与启动
下载地址: https://www.mongodb.com/try/download/community
mac 参考 mongodb 下载安装
windows 参考 视频教程
mac 中全局变量配置完以后,mongod 启动服务的命令必须要在 bin 目录下才能使用,mongo 启动数据库命令,可以全局使用。
1、数据库命令
- 显示所有的数据库
show dbs
- 切换到指定的数据库,如果数据库不存在会自动创建数据库
use 数据库名
- 显示当前所在数据库
db
- 删除当前数据库
use 数据库名
db.dropDatabase()
2、集合命令
- 创建集合
db.createCollection('集合名称')
- 显示当前数据库中所有集合
show collections
- 删除某个集合
db.集合名.drop()
- 重命名
db.集合名.renameCollection('newName')
3、文档命令
- 插入文档
db.集合名.insert(文档对象)
db.account.insert({name:'wangwu', age: 20})
- 查询文档
db.集合名.find(查询条件)
db.account.find({name:'wangwu'})
没有查询条件,就查集合里面所有的文档 - 更新文档
db.集合名.update(查询条件,新的文档)
db.account.update({name:'lisi'},{name:'lisi222'})
上面两个 新文档 会覆盖 旧文档
db.集合名.update(查询条件, {$set:更新文档})
db.account.update({name:'jeck'},{$set:{age:22}})
上面命令是只修改某一项或多项,不会直接覆盖 - 删除文档
db.集合名.remove(查询条件)
db.account.remove({name:'lisi222'})
4、应用场景
4-1、新增
- 用户注册
- 发布视频
- 发布商品
- 发朋友圈
- 发评论
- 发微博
- 发弹幕
- …
4-2、删除
- 删除评论
- 删除商品
- 删除文章
- 删除视频
- 删除微博
- …
4-3、更新
- 更新个人信息
- 修改商品价格
- 修改文章内容
- …
4-4、查询
- 商品列表
- 视频列表
- 朋友圈列表
- 微博列表
- 搜索功能
- …
二、Mongoose
1、介绍
Mongoose 是一个对象文档模型库,官网 http://www.mongoosejs.net/添加链接描述
2、作用
方便使用代码操作 mongodb 数据库
3、使用流程
- 安装 mongoose
npm install mongoose
- 导入 mongoose
// 导入 mongoose
// 1、导入 mogoose
const mongoose = require('mongoose')
const { type } = require('os')// 2、连接 mongdb 服务器
mongoose.connect('mongodb://127.0.0.1:27017/bilibili')// 3、设置回调
mongoose.connection.once('open', () => {// console.log('连接成功')// 4、创建文档的结构对象// let BookSchema = new mongoose.Schema({// name: String,// author: String,// author_gemder: String,// price: Number,// is_hot: Boolean,// tags: Array,// create_time: Date// })// 字段校验let BookSchema = new mongoose.Schema({name: {type: String, // 设置类型require: true, // 设置必填项unique: true // 设置唯一值},author: {type: String, // 设置类型default: '佚名' // 设置默认值},author_gemder: {type: String,enum: ['男', '女', '未知'] // 设置枚举值(值只能从这里取其一)},price: Number,is_hot: Boolean,tags: Array,create_time: Date})// 5、创建模型对象 对文档操作的封装对象(可以完成对文档的增删改查操作)// 第一个参数 book 是集合(数组)名称,第二个参数 BookSchema 是结构对象let BookModel = mongoose.model('book', BookSchema)// 6、新增基本对象// 如果属性跟上面定义的属性不统一,在写入数据库时会忽略这个键值对// 如果属性值的类型跟上面定义的类型不同意,写入时会报错,写入失败BookModel.create({name: '西游记',author: '吴承恩',price: 19.9,is_hot: true,tags: ['言情','都市','恐怖','玄幻'],create_time: new Date(),author_gemder: '男'}).then((data) => {// 输出成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
})mongoose.connection.on('error', () => {console.log('连接失败')
})mongoose.connection.on('close', () => {console.log('关闭连接')
})// setTimeout(() => {
// // 关闭数据库连接
// mongoose.disconnect()
// }, 3000)
4、字段类型
文档结构可选的常用字段类型列表:
5、字段值验证
Mongoose 有一些内建验证器,可以对字段值进行验证
5-1、必填项
title: { type: String, required: true // 设置必填项
},
5-2、默认值
author: { type: String, default: '匿名' //默认值
},
5-3、枚举值
gender: { type: String, enum: ['男','女'] //设置的值必须是数组中的
},
5-4、唯一值
username: { type: String, unique: true
},
unique 需要 重建集合 才能有效果
永远不要相信用户的输入
6、增删改查
数据库基本操作包括四个,增加(create),删除(delete),修改(update),查(read),其操作都是在mongoose.connection.once('open', () => {})
回调中进行的
6-1、增加
插入一条:
// 1、导入 mogoose
const mongoose = require('mongoose')// 2、连接 mongdb 服务器
mongoose.connect('mongodb://127.0.0.1:27017/bilibili')// 3、设置回调
mongoose.connection.once('open', () => {// console.log('连接成功')// 4、创建文档的结构对象let BookSchema = new mongoose.Schema({name: String,author: String,price: Number})// 5、创建模型对象 对文档操作的封装对象(可以完成对文档的增删改查操作)// 第一个参数 book 是集合(数组)名称,第二个参数 BookSchema 是结构对象let BookModel = mongoose.model('book', BookSchema)// 6、新增基本对象// 如果属性跟上面定义的属性不统一,在写入数据库时会忽略这个键值对// 如果属性值的类型跟上面定义的类型不同意,写入时会报错,写入失败BookModel.create({name: '西游记',author: '吴承恩',price: 19.9}).then((data) => {// 输出 插入成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
})mongoose.connection.on('error', () => {console.log('连接失败')
})mongoose.connection.on('close', () => {console.log('关闭连接')
})// setTimeout(() => {
// // 关闭数据库连接
// mongoose.disconnect()
// }, 3000)
插入多条:
BookModel.insertMany([ { name:'华为', color:'灰色', price:2399, tags:['电量大','屏幕大','信号好'] },{ name:'小米', color:'白色', price:2099, tags:['电量大','屏幕大','信号好'] } ],(data)=>{ console.log('写入成功');mongoose.connection.close();
})
6-2、删除
删除一条:
BookModel.deleteOne({_id:'669f4719bbf7718b48b790ed'}).then((data) => {// 输出 插入成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
删除多条:
BookModel.deleteMany({is_hot: false}).then((data) => {// 输出 插入成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
6-3、文档更新
单条文档更新 BookModel.updateOne({}, {}).then()
多条文档更新BookModel.updateMany({}, {}).then()
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');//设置 strictQuery 为 true
mongoose.set('strictQuery', true);//3. 连接 mongodb 服务 数据库的名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');//4. 设置回调
// 设置连接成功的回调 once 一次 事件回调函数只执行一次
mongoose.connection.once('open', () => {//5. 创建文档的结构对象//设置集合中文档的属性以及属性值的类型let BookSchema = new mongoose.Schema({name: String,author: String,price: Number,is_hot: Boolean});//6. 创建模型对象 对文档操作的封装对象 mongoose 会使用集合名称的复数, 创建集合let BookModel = mongoose.model('novel', BookSchema);//7. 更新文档// 更新单个文档 updateOne 接收两个参数,第一个是条件,第二个是新的对象// BookModel.updateOne({name: '西游记'}, {price: 9.9}).then((data) => {// // 输出 插入成功后的文档对象// console.log(data)// // 7、关闭数据库连接(项目运行过程中,不会添加该代码)// mongoose.disconnect()// }).catch(res => {// console.error('捕捉到了错误信息'+res)// )// 更新多个文档BookModel.updateMany({is_hot: false}, {is_hot: true}).then((data) => {// 输出 插入成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})});// 设置连接错误的回调
mongoose.connection.on('error', () => {console.log('连接失败');
});//设置连接关闭的回调
mongoose.connection.on('close', () => {console.log('连接关闭');
});
6-4、查询文档
查询一条数据:BookModel.findOne({name:'23'}).then()
根据 ID 查询数据BookModel.findById(‘’).then()
批量查询数据:BookModel.find({}).then()
(有条件就根据条件查询,没条件就查所有的)
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');//设置 strictQuery 为 true
mongoose.set('strictQuery', true);//3. 连接 mongodb 服务 数据库的名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');//4. 设置回调
// 设置连接成功的回调 once 一次 事件回调函数只执行一次
mongoose.connection.once('open', () => {//5. 创建文档的结构对象//设置集合中文档的属性以及属性值的类型let BookSchema = new mongoose.Schema({name: String,author: String,price: Number,is_hot: Boolean});//6. 创建模型对象 对文档操作的封装对象 mongoose 会使用集合名称的复数, 创建集合let BookModel = mongoose.model('novel', BookSchema);//7. 读取文档// 按照条件读取文档BookModel.findOne({name:'狂飙'}).then((data) => {// 输出 插入成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})// 通过 id 读取文档// BookModel.findById('669f4ef193ea628ad18eeb33')//.then((data) => {// console.log(data)// mongoose.disconnect()//}).catch(res => {// console.error('捕捉到了错误信息'+res)// })// 读取所有文档// BookModel.find().then((data) => {// console.log(data)// mongoose.disconnect()//}).catch(res => {// console.error('捕捉到了错误信息'+res)// })});// 设置连接错误的回调
mongoose.connection.on('error', () => {console.log('连接失败');
});//设置连接关闭的回调
mongoose.connection.on('close', () => {console.log('连接关闭');
});
7、条件控制
7-1、运算符
在 mongodb 中不能使用 >, <, >=,<=,!==等运算符,需要使用替代符号
>
使用$gt
<
使用$lt
>=
使用$gte
<=
使用$lte
!==
使用$ne
// 查询价格小于 20 的文档
BookModel.find({price:{$lt: 20}}).then((data) => {// 输出 插入成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
7-2、逻辑运算符
$or
逻辑或
$and
逻辑与
// 逻辑运算 - 查询 name 为 余华 或者 刘慈欣 的文档
BookModel.find({$or: [{author: '余华'},{author: '刘慈欣'}]}).then((data) => {// 输出 插入成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
7-3、正则匹配
条件中可以直接使用 js 的正则语法,通过正则可以进行模糊查询
// 正则匹配 - 查询 name 包含 ‘三’ 的文档
BookModel.find({name: /三/})
BookModel.find({name: new RegExp('三')})
8、个性化读取
8-1、字段筛选
取前端需要展示的字段,_id 会默认取出来,,如果不需要,要设为 0
// 字段筛选(取某些字段,0 不要的字段,1 要获取的字段)
BookModel
.find()
.select({name: 1, author: 1, price: 1, _id: 0})
.then((data) => {// 输出 插入成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
8-2、数据排序
// 数据排序,1:升序,-1:倒序
BookModel
.find()
.select({name:1, price:1, _id: 0})
.sort({price: 1})
.then((data) => {// 输出 插入成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
8-3、数据截取
常用来做分页,skip 为 (页码 - 1) * limit 中的值
// 数据截取,limit 接收一个参数,为要截取的数据的长度,skip接收一个参数,表示在截取前,要跳过几个数据,常用作分页BookModel.find().select({name:1, price:1, _id: 0}).sort({price: 1}).skip(3).limit(3).then((data) => {// 输出 插入成功后的文档对象console.log(data)// 7、关闭数据库连接(项目运行过程中,不会添加该代码)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
9、模块化
config.js
module.exports = {DBHOST: '127.0.0.1',DBPORT: '27017',DBNAME: 'bilibili'
}
db.js
module.exports = function (success, error = () => {console.log('连接失败了啊')}) {// 1、导入 mogooseconst mongoose = require('mongoose')const { DBHOST, DBPORT, DBNAME } = require('../config/config')// 2、连接 mongdb 服务器mongoose.connect(`mongodb://${DBHOST}:${DBPORT}/${DBNAME}`)// 3、设置回调mongoose.connection.once('open', () => {success()})mongoose.connection.on('error', () => {error()})mongoose.connection.on('close', () => {console.log('关闭连接')})
}
BookModel.js
const mongoose = require('mongoose')let MovieSchema = mongoose.Schema({name: String,director: String
})
let MovieModel = new mongoose.model('movie', MovieSchema)module.exports = MovieModel
book.js
const db = require('./db/db')
const BookModel = require('./models/BookModel')db(() => {BookModel.create({name: '阿勒泰',author: '阿勒泰',price: 88.8}).then((data) => {console.log(data)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
})
MovieModel.js
const mongoose = require('mongoose')let MovieSchema = new mongoose.Schema({name: String,director: String
})
let MovieModel = mongoose.model('movie', MovieSchema)module.exports = MovieModel
movie.js
const db = require('./db/db')
const MovieModel = require('./models/MovieModel')db(() => {MovieModel.create({name: '第二十条',director: '张艺谋'}).then((data) => {console.log(data)mongoose.disconnect()}).catch(res => {console.error('捕捉到了错误信息'+res)})
})
四、图形化管理工具
我们可以使用图形化的管理工具来对 Mongodb 进行交互,这里演示两个图形化工具
- Robo 3T 免费 https://github.com/Studio3T/robomongo/releases
- Navicat 收费 https://www.navicat.com.cn/