1. 简介
1-1. Mongodb 是什么
MongoDB 是一个基于分布式文件存储的数据库,官方地址 www.mongodb.com/
1-2. 数据库是什么
数据库(DataBase)是按照数据结构来组织、存储和管理数据的 应用程序
1-3. 数据库的作用
数据库的主要作用就是 管理数据 ,对数据进行 增(c)、删(d)、改(u)、查(r)
1-4. 数据库管理数据的特点
相比于纯文件管理数据,数据库管理数据有如下特点:
- 速度更快
- 扩展性更强
- 安全性更强
1-5. 为什么选择 Mongodb
操作语法与 JavaScript 类似,容易上手,学习成本低
2. 核心概念
Mongodb 中有三个重要概念需要掌握
- 数据库(database) 数据库是一个数据仓库,数据库服务下可以创建很多数据库,数据库中可以存 放很多集合
- 集合(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": "情人节聚餐"
},
{
"id": "mRQiD4s3K",
"title": "发工资",
"time": "2023-02-19",
"type": "1",
"account": "4396",
"remarks": "终于发工资啦!~~"
}
],
"users":[
{
"id": 1,
"name": "zhangsan",
"age": 18
},
{
"id": 2,
"name": "lisi",
"age": 20
},
{
"id": 3,
"name": "wangwu",
"age": 22
}
]
}
大家可以通过 JSON 文件来理解 Mongodb 中的概念:
- 一个
JSON 文件好比是一个数据库,一个 Mongodb 服务下可以有 N 个数据库 - JSON 文件中的
一级属性的数组值好比是集合 - 数组中的对象好比是
文档 - 对象中的属性有时也称之为
字段
一般情况下:
- 一个项目使用一个数据库
- 一个集合会存储同一种类型的数据
3. 下载安装与启动
下载地址: www.mongodb.com/try/downloa…
建议选择 zip 类型, 通用性更强
配置步骤如下:
-
将压缩包移动到
C:\Program Files下,然后解压 -
创建
C:\data\db目录,mongodb 会将数据默认保存在这个文件夹 -
以 mongodb 中 bin 目录作为工作目录,启动命令行
-
运行命令
mongod
看到最后的 waiting for connections 则表明服务 已经启动成功
然后可以使用 mongo 命令连接本机的 mongodb 服务
注意:
- 为了方便后续方便使用 mongod 命令,可以将 bin 目录配置到环境变量 Path 中
千万不要选中服务端窗口的内容,选中会停止服务,可以敲回车取消选中
4. 命令行交互
命令行交互一般是学习数据库的第一步,不过这些命令在后续用的比较少,所以大家了解即可
4-1. 数据库命令
-
显示所有的数据库
show dbs -
切换到指定的数据库,如果数据库不存在会自动创建数据库
use 数据库名 -
显示当前所在的数据库
db -
删除当前数据库
use 库名 db.dropDatabase()
4-2. 集合命令
-
创建集合
db.createCollection('集合名称') -
显示当前数据库中的所有集合
show collections -
删除某个集合
db.集合名.drop() -
重命名集合
db.集合名.renameCollection('newName')
4-3. 文档命令
-
插入文档
db.集合名.insert(文档对象); -
查询文档
db.集合名.find(查询条件)_id 是 mongodb 自动生成的唯一编号,用来唯一标识文档 -
更新文档
db.集合名.update(查询条件,新的文档) db.集合名.update({name:'张三'},{$set:{age:19}}) -
删除文档
db.集合名.remove(查询条件)
4-4. 应用场景
4-4-1. 新增
- 用户注册
- 发布视频
- 发布商品
- 发朋友圈
- 发评论
- 发微博
- 发弹幕
- ······
4-4-5. 删除
- 删除评论
- 删除商品
- 删除文章
- 删除视频
- 删除微博
- ······
4-4-6. 更新
- 更新个人信息
- 修改商品价格
- 修改文章内容
- ······
4-4-7. 查询
- 商品列表
- 视频列表
- 朋友圈列表
- 微博列表
- 搜索功能
- ······
5. Mongoose
5-1. 介绍
Mongoose 是一个对象文档模型库,官网 www.mongoosejs.net/
5-2. 作用
方便使用代码操作 mongodb 数据库
5-3. 使用流程
//1. 安装 mongoose
//2. 导入 mongoose
const mongoose = require('mongoose');
//3. 连接数据库
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
//4. 设置连接回调
//连接成功
mongoose.connection.on('open', () => {
console.log('连接成功');
//5. 创建文档结构对象
let BookSchema = new mongoose.Schema({
title: String,
author: String,
price: Number
});
//6. 创建文档模型对象
let BookModel = mongoose.model('books', BookSchema);
//7. 插入文档
let book = {
name:'西游记',
author:'吴承恩',
price:39.9
}
// BookModel.create(book,(err,data) => { // 旧版的写法,新版本已经不再支持回调函数,需用promise的写法
// // 判断是否有错误
// if(err) {
// console.log(err);
// return
// }
// // 如果没有出错,则输出插入后的文档对象
// console.log(data);
// })
BookModel.create(book).then((data) => {
console.log(data);
}).catch(err => {
console.log(err);
})
});
//连接出错
mongoose.connection.on('error', () => {
console.log('连接出错~~');
})
//连接关闭
mongoose.connection.on('close', () => {
console.log('连接关闭');
})
5-4. 字段类型
文档结构可选的常用字段类型列表
| 类型 | 描述 |
|---|---|
| String | 字符串 |
| Number | 数字 |
| Boolean | 布尔值 |
| Array | 数组,也可以使用 [] 来标识 |
| Date | 日期 |
| Buffer | Buffer 对象 |
| Mixed | 任意类型,需要使用 mongoose.Schema.Types.Mixed 指定 |
| ObjectId | 对象 ID,需要使用 mongoose.Schema.Types.ObjectId 指定 |
| Decimal128 | 高精度数字,需要使用 mongoose.Schema.Types.Decimal128 指定 |
5-5. 字段值验证
Mongoose 有一些内建验证器,可以对字段值进行验证
5-5-1. 必填项
title: {
type: String,
required: true // 设置必填项
},
5-5-2. 默认值
author: {
type: String,
default: '匿名' //默认值
},
5-5-3. 枚举值
gender: {
type: String,
enum: ['男','女'] //设置的值必须是数组中的
},
5-5-4. 唯一值
username: {
type: String,
unique: true
},
unique 需要
重建集合才能有效果 永远不要相信用户的输入
5-6. CURD
数据库的基本操作包括四个,增加(create),删除(delete),修改(update),查(read)
5-6-1. 增加
插入一条数据
let book = {
name: '水浒传',
author: '施耐庵',
price: 59.9,
des: '这是一段描述~',
style: '志怪'
}
/**第一种写法(已弃用) */
// BookModel.create(book,(err,data) => {
// // 判断是否有错误
// if(err) {
// console.log(err);
// return
// }
// // 如果没有出错,则输出插入后的文档对象
// console.log(data);
// })
/**第二种写法 */
// BookModel.create(book).then((data) => {
// console.log(data);
// //8. 断开连接
// mongoose.disconnect();
// }).catch(err => {
// console.log(err);
// })
/**第三种写法(推荐) */
try {
const data = await BookModel.create(book);
console.log('插入成功--', data);
//8. 断开连接
mongoose.disconnect();
} catch (error) {
console.log('插入失败--', error);
}
批量插入
// 1.安装mongoose
// 2.导入
const mongoose = require('mongoose');
// 3.连接 mongodb 服务 数据库名称
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
// 4.设置回调
// 设置连接成功的回调
mongoose.connection.once('open', async () => {
// 5.创建文档结构对象
// 设置集合中文档的属性和属性值的类型
let BookSchema = new mongoose.Schema({
name: {
type: String,
unique: true
},
author: String,
price: Number,
style: {
type: String,
enum: ['言情', '城市', '志怪','侠义','战争']
}
})
// 6.创建模型对象
let BookModel = mongoose.model('levels', BookSchema);
// 7.新增
let books = [{
name: '水浒传',
author: '施耐庵',
price: 39.9,
style: '侠义'
},{
name: '西游记',
author: '吴承恩',
price: 59.9,
style: '志怪'
},{
name: '红楼梦',
author: '曹雪芹',
price: 19.9,
style: '言情'
},{
name: '三国演义',
author: '罗贯中',
price: 29.9,
style: '战争'
}]
/**第三种写法 */
try {
const data = await BookModel.insertMany(books);
console.log('插入成功--', data);
//8. 断开连接
mongoose.disconnect();
} catch (error) {
console.log('插入失败--', error);
}
});
// 设置连接错误的回调
mongoose.connection.on('error', () => {
console.log('连接失败');
});
// 设置连接关闭的回调
mongoose.connection.on('close', () => {
console.log('连接关闭');
});
// 关闭mongodb的连接
// setTimeout(() => {
// mongoose.disconnect();
// }, 2000);
5-6-2. 删除
删除一条数据
SongModel.deleteOne({_id:'5dd65f32be6401035cb5b1ed'}).then(() => {
console.log('删除成功');
mongoose.connection.close();
}).catch(err => {
console.log('删除失败');
});
批量删除
SongModel.deleteMany({author:'Jay'}).then(() => {
console.log('删除成功');
mongoose.connection.close();
}).catch(err => {
console.log('删除失败');
});
5-6-3. 更新
更新一条数据
SongModel.updateOne({name: '红楼梦'},{price:9.9}).then(() => {
console.log('更新成功');
mongoose.connection.close();
}).catch(err => {
console.log('更新失败');
});
批量更新数据
SongModel.updateMany({author: '余华'}, {is_hot: true}).then(() => {
console.log('更新成功');
mongoose.connection.close();
}).catch(err => {
console.log('更新失败');
});
5-6-4. 查询
查询一条数据
SongModel.findOne({name: '红楼梦'}).then(data => {
console.log(data);
mongoose.connection.close();
}).catch(err => {
throw err;
});
//根据 id 查询数据
SongModel.findById('5dd662b5381fc316b44ce167').then((data) => {
console.log(data);
mongoose.connection.close();
}).catch((err) => {
console.log('查询失败');
});
批量查询数据
//不加条件查询
SongModel.find().then((data) => {
console.log(data);
mongoose.connection.close();
}).catch(err => {
console.log('查询失败');
})
//加条件查询
SongModel.find({author: '余华'}).then(data => {
console.log(data);
mongoose.connection.close();
}).catch(err => {
console.log('查询失败');
});
5-7. 条件控制
5-7-1. 运算符
在 mongodb 不能 > < >= <= !== 等运算符,需要使用替代符号
>使用$gt<使用$lt>=使用$gte<=使用lte!==使用$ne
db.students.find({id:{$gt:3}}); //id号比3大的所有的记录
5-7-2. 逻辑运算
$or 逻辑或的情况
db.students.find({$or:[{age:18},{age:24}]});
$and 逻辑与的情况
db.students.find({$and: [{age: {$lt:20}}, {age: {$gt: 15}}]});
5-7-3. 正则匹配
条件中可以直接使用 JS 的正则语法,通过正则可以进行模糊查询
db.students.find({name:/imissyou/});
// 如果是匹配一个变量,可使用以下写法
let str = 'imissyou'
db.students.find({name: new RegExp(str)});
5-8. 个性化读取
5-8-1. 字段筛选
//0:不要的字段
//1:要的字段
SongModel.find().select({_id:0,title:1}).exec(function(err,data){
if(err) throw err;
console.log(data);
mongoose.connection.close();
});
5-8-2. 数据排序
//sort 排序
//1:升序
//-1:倒序
SongModel.find().sort({hot:1}).exec(function(err,data){
if(err) throw err;
console.log(data);
mongoose.connection.close();
});
5-8-3. 数据截取
//skip 跳过 limit 限定
SongModel.find().skip(10).limit(10).exec(function(err,data){
if(err) throw err;
console.log(data);
mongoose.connection.close();
});
5-9. Mongoose代码模块化
代码模块化的目的是为了更好的维护代码,减少代码量,避免重复的逻辑书写代码。
-
首先根目录新建
db文件夹,新建db/db.js文件,在此文件封装连接Mongodb数据库的相关操作。/** * @param {*} success 数据库连接成功的回调 * @param {*} error 数据库连接失败的回调 */ module.exports = function (success, error) { // 1.安装mongoose // 2.导入 const mongoose = require('mongoose'); // 导入配置文件 const { DBHOST, DBNAME, DBPORT } = require('../config/config'); // 3.连接 mongodb 服务 数据库名称 mongoose.connect(`mongodb://127.0.0.1:27017/bilibili`); // 4.设置回调 // 设置连接成功的回调 mongoose.connection.once('open', () => { success(); }); // 设置连接错误的回调 mongoose.connection.on('error', () => { error(); }); // 设置连接关闭的回调 mongoose.connection.on('close', () => { console.log('连接关闭'); }); } -
根目录index.js中调用
// 导入db文件 const db = require('./db/db'); // 导入mongoose const mongoose = require('mongoose'); db(()=> { console.log('连接成功'); }, () => { console.log('连接失败'); }) -
根目录创建
models文件夹,存放文档模型对象bookmodel.js// 导入mongoose const mongoose = require('mongoose'); // 创建文档结构对象 // 设置集合中文档的属性和属性值的类型 let BookSchema = new mongoose.Schema({ name: { type: String, unique: true }, author: String, price: Number }) // 创建模型对象 let BookModel = mongoose.model('books', BookSchema); // 暴露模型对象 module.exports = BookModel; -
在
index.js文件中引入bookmodel.js,进行相关数据库操作// 导入db文件 const db = require('./db/db'); // 导入mongoose const mongoose = require('mongoose'); // 导入bookmodel const BookModel = require('./models/bookmodel'); db(async()=> { // 新增 let book = { name: '三国演义', author: '罗贯中', price: 69.9, style: '战争' } // 插入数据 try { const data = await BookModel.create(book); console.log('成功--', data); //8. 断开连接 mongoose.disconnect(); } catch (error) { console.log('失败--', error); } }, () => { console.log('连接失败'); }) -
优化
db.js判断
error为其设置默认值,调用时可不传error函数/** * @param {*} success 数据库连接成功的回调 * @param {*} error 数据库连接失败的回调 */ module.exports = function (success, error) { // 判断error 为其设置默认值 if (typeof err !== 'function') { error = () => { console.log('连接失败'); } } ······ }单独配置数据库连接,新建
config/config.js配置文件// 配置文件 module.exports = { DBHOST:'127.0.0.1', DBPORT: 27017, DBNAME:'bilibili' }db.js中导入配置文件,将数据库连接设置成变量/** * @param {*} success 数据库连接成功的回调 * @param {*} error 数据库连接失败的回调 */ module.exports = function (success, error) { ······ // 导入配置文件 const { DBHOST, DBNAME, DBPORT } = require('../config/config'); // 3.连接 mongodb 服务 数据库名称 mongoose.connect(`mongodb://${DBHOST}:${DBPORT}/${DBNAME}`); ······ }优化后的
db.js/** * @param {*} success 数据库连接成功的回调 * @param {*} error 数据库连接失败的回调 */ module.exports = function (success, error) { // 判断error 为其设置默认值 if (typeof err !== 'function') { error = () => { console.log('连接失败'); } } // 1.安装mongoose // 2.导入 const mongoose = require('mongoose'); // 导入配置文件 const { DBHOST, DBNAME, DBPORT } = require('../config/config'); // 3.连接 mongodb 服务 数据库名称 mongoose.connect(`mongodb://${DBHOST}:${DBPORT}/${DBNAME}`); // 4.设置回调 // 设置连接成功的回调 mongoose.connection.once('open', () => { success(); }); // 设置连接错误的回调 mongoose.connection.on('error', () => { error(); }); // 设置连接关闭的回调 mongoose.connection.on('close', () => { console.log('连接关闭'); }); }
6. 图形化管理工具
我们可以使用图形化的管理工具来对 Mongodb 进行交互,这里演示两个图形化工具
- Robo 3T 免费 github.com/Studio3T/ro…
- Navicat 收费 www.navicat.com.cn/