MongoDB
一、简介
1.1 Mongodb 是什么
MongoDB 是一个基于分布式文件存储的数据库,官方地址 www.mongodb.com/
1.2 数据库是什么
数据库(DataBase)是按照数据结构来组织、存储和管理数据的 应用程序
1.3 数据库的作用
数据库的主要作用就是 管理数据 ,对数据进行 增(c)、删(d)、改(u)、查(r)
1.4 数据库管理数据的特点
相比于纯文件管理数据,数据库管理数据有如下特点:
-
速度更快
-
扩展性更强
-
安全性更强
1.5 为什么选择 Mongodb
操作语法与 JavaScript 类似,容易上手,学习成本低
二、核心概念
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 文件中的 一级属性的数组值 好比是 集合
数组中的对象好比是 文档
对象中的属性有时也称之为 字段 一般情况下 一个项目使用一个数据库 一个集合会存储同一种类型的数据
三、下载安装与启动
下载地址: www.mongodb.com/try/downloa…
建议选择 zip 类型, 通用性更强
配置步骤如下:
1> 将压缩包移动到 C:\Program Files 下,然后解压
2> 创建 C:\data\db 目录,mongodb 会将数据默认保存在这个文件夹
3> 以 mongodb 中 bin 目录作为工作目录,启动命令行
4> 运行命令 mongod
看到最后的 waiting for connections 则表明服务 已经启动成功
然后可以使用 mongo 命令连接本机的 mongodb 服务
注意: 为了方便后续方便使用 mongod 命令,可以将 bin 目录配置到环境变量 Path 中 千万不要选中服务端窗口的内容 ,选中会停止服务,可以 敲回车 取消选中
四、命令行交互
命令行交互一般是学习数据库的第一步,不过这些命令在后续用的比较少,所以大家了解即可
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.2 删除
删除评论
删除商品
删除文章
删除视频
删除微博
五、Mongoose
5.1 介绍
Mongoose 是一个对象文档模型库,官网 www.mongoosejs.net/
5.2 作用
方便使用代码操作 mongodb 数据库
5.3 使用流程
//1. 安装 mongoose
npm i mongoose@6
// 2.导入mongoose
const mongoose=require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/bilibili')
// 设置连接成功回到//once只执行一次
mongoose.connection.once('open',() => {
console.log('连接成功 -----> ');
})
// 设置连接错误回调
mongoose.connection.on('error',() => {
console.log('连接失败 -----> ');
})
// 设置连接关闭回调
mongoose.connection.on('close',() => {
console.log('连接关闭 -----> ');
})
const mongoose=require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/bilibili')
// 设置连接成功回到
mongoose.connection.once('open',() => {
// 设置集合中的文档的属性以及属性值的类型
let BookSchema=new mongoose.Schema({
name:String,
author:String,
price:Number
})
// 6.创建模型对象 对文档操作的封装地域性
let BoolModel=mongoose.model('books',BookSchema)
// 新增
BoolModel.create({
name:'西游记',
auther:"吴承恩",
price:19.9
},(err,data)=>{
// 判断是否有错误
if(err){
console.log(err)
return
}
console.log(data);
// 关闭数据库连接
mongoose.disconnect()
})
})
// 设置连接错误回调
mongoose.connection.on('error',() => {
console.log('连接失败 -----> ');
})
// 设置连接关闭回调
mongoose.connection.on('close',() => {
console.log('连接关闭 -----> ');
})
5.4 字段类型
文档结构可选的常用字段类型列表
const mongoose=require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/bilibili')
// 设置连接成功回到
mongoose.connection.once('open',() => {
// 设置集合中的文档的属性以及属性值的类型
let BookSchema=new mongoose.Schema({
name:String,
author:String,
price:Number,
is_hot:Boolean,
tags:Array,
pub_time:Date,
test:mongoose.Schema.Types.Mixed,//任意类型
text:mongoose.Schema.Types.ObjectId//文档Id
})
// 6.创建模型对象 对文档操作的封装地域性
let BoolModel=mongoose.model('books',BookSchema)
// 新增
BoolModel.create({
name:'西游记',
auther:"吴承恩",
price:19.9,
is_hot:true,
tags:['爱国','敬业','诚信','友善'],
pub_time:new Date(),
test:'123'
},(err,data)=>{
// 判断是否有错误
if(err){
console.log(err)
return
}
console.log(data);
// 关闭数据库连接
mongoose.disconnect()
})
})
// 设置连接错误回调
mongoose.connection.on('error',() => {
console.log('连接失败 -----> ');
})
// 设置连接关闭回调
mongoose.connection.on('close',() => {
console.log('连接关闭 -----> ');
})
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 需要 重建集合 才能有效果
永远不要相信用户的输入
代码演示
// 1.安装mongoose
// 2.导入mongoose
const mongoose=require('mongoose')
mongoose.connect('mongodb://127.0.0.1:27017/bilibili')
// 设置连接成功回到
mongoose.connection.once('open',() => {
// 设置集合中的文档的属性以及属性值的类型
let BookSchema=new mongoose.Schema({
name:{
type:String,
require:true//表面该属性必须不为空
},
author:{
type:String,
default:'匿名'//默认值
},
style:{
type:String,
// 枚举
enum:['男','女','两者都不是','沃尔玛购物袋']
},
price:Number
})
// 6.创建模型对象 对文档操作的封装地域性
let BoolModel=mongoose.model('book',BookSchema)
// 新增
BoolModel.create({
name:'西游记',
author:"吴承恩",
style:'沃尔玛购物袋',
price:19.9
},(err,data)=>{
// 判断是否有错误
if(err){
console.log(err)
return
}
console.log(data);
// 关闭数据库连接
mongoose.disconnect()
})
})
// 设置连接错误回调
mongoose.connection.on('error',() => {
console.log('连接失败 -----> ');
})
// 设置连接关闭回调
mongoose.connection.on('close',() => {
console.log('连接关闭 -----> ');
})
5.6 CURD
数据库的基本操作包括四个,增加(create),删除(delete),修改(update),查(read)
5.6.1 删除
显示当前数据库中的所有集合
show collections
- 查询文档
db.集合名.find()
删除一条数据
SongModel.deleteOne({_id:'5dd65f32be6401035cb5b1ed'}, (err,data)=>{
if(err) {
console.log('删除失败~~')
return
}
console.log(data);
})
SongModel.deleteMany({is_hot:false}, (err,data)=>{
if(err) {
console.log('删除失败~~')
return
}
console.log(data);
})
5.6.2 更新
更新一条数据
SongModel.updateOne({author: 'JJ Lin'}, {author: '林俊杰'}, (err,data)=> {
if(err) {
console.log('更新失败~~')
}
console.log(data);
})
更新多条数据
SongModel.updateMany({author: 'Leehom Wang'}, {author: '王力宏'}, (err,data)=> {
if(err) {
console.log(更新失败~~)
}
console.log(data);
});
5.6.3 增加
插入一条
SongModel.create({
title:'给我一首歌的时间',
author: 'Jay'
}, function(err, data){
//错误
if(err) {
console.log(增加失败~~)
}
console.log(data);
});
});
批量插入
//1.引入mongoose
const mongoose = require('mongoose');
//2.链接mongodb数据库 connect 连接
mongoose.connect('mongodb://127.0.0.1:27017/project');
//3.设置连接的回调
mongoose.connection.on('open',()=>{
//4.声明文档结构
const PhoneSchema = new mongoose.Schema({
brand:String,
color:String,
price:Number,
tags:Array
})
//6.创建模型对象
const PhoneModel = mongoose.model('phone',PhoneSchema);
PhoneModel.insertMany([
{
brand:'华为',
color:'灰色',
price:2399,
tags:['电量大','屏幕大','信号好']
},
{
brand:'小米',
color:'白色',
price:2099,
tags:['电量大','屏幕大','信号好']
}
],(err,data)=>{
if(err) throw err;
console.log('写入成功');
mongoose.connection.close();
})
})
5.6.4 查询
查询一条数据
SongModel.findOne({author: '王力宏'}, (err, data)=>{
//错误
if(err) {
console.log(查询失败~~)
}
console.log(data);
});
});
//根据 id 查询数据
SongModel.findById('5dd662b5381fc316b44ce167',(err, data)=>{
if(err) {
console.log(查询失败~~)
}
console.log(data);
});
});
批量查询数据
//不加条件查询
SongModel.find(function(err, data)=>{
if(err) throw err;
console.log(data);
mongoose.connection.close();
});
//加条件查询
SongModel.find({author: '王力宏'}, function(err, data)=>{
if(err) throw err;
console.log(data);
mongoose.connection.close();
})
});
//加条件查询
SongModel.find({author: '王力宏'}, (err, data)=>{
//不加条件查询
SongModel.find(function(err, data){
if(err) throw err;
console.log(data);
mongoose.connection.close();
});
//加条件查询
SongModel.find({author: '王力宏'}, (err, data)=>{
if(err) throw err;
console.log(data);
mongoose.connection.close();
})
})
5.7 条件控制
5.7.1 运算符
在 mongodb 不能 > < >= <= !== 等运算符,需要使用替代符号
> 使用 $gt
< 使用 $lt
>= 使用 $gte
<= 使用 $lte
!== 使用 $ne
db.students.find({id:{$gt:3}}); id号比3大的所有的记录 代码演示: 价格小于20
BoolModel.fine({price:{$lt:20}},(err,data) => {
if(err){
console.log(' -----> 读取失败');
return
}
console.log( data);
})
5.7.2 逻辑运算
$or 逻辑或的情况
db.students.find({$or:[{age:18},{age:24}]})
代码演示 曹雪芹或者余华
BoolModel.fine({$or:[{author:'曹雪芹'},{author:'玉华'}]},(err,data) => {
if(err){
console.log(' -----> 读取失败');
return
}
console.log( data);
})
$and 逻辑与的情况
db.students.find({and: [{age: {lt:20}}, {age: {$gt: 15}}]});
代码演示 价格大于30且小于70
BoolModel.fine({$and:[{price:{$gt:30}},{price:{$lt:70}}]},(err,data) => {
if(err){
console.log(' -----> 读取失败');
return
}
console.log( data);
})
5.7.3 正则匹配
条件中可以直接使用 JS 的正则语法,通过正则可以进行模糊查询
db.students.find({name:/imissyou/});
代码演示 正则表达式,搜索书籍名称带有“三”的图书
BoolModel.fine({name:/三/},(err,data) => {
if(err){
console.log(' -----> 读取失败');
return
}
console.log( data);
})
或者
BoolModel.fine({name:new RegExp('三')},(err,data) => {
if(err){
console.log(' -----> 读取失败');
return
}
console.log( data);
})
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();
});
六、mongoose代码模块化
把代码分离出来,进行模块化处理
db
module.exports=function(success,error){
const mongoose=require('mongoose')
mongoose.set('strictQuery',true)
mongoose.connect('mongodb://127.0.0.1:27017/bilibili')
mongoose.connection.once('open',() => {
success()
})
// 设置连接错误回调
mongoose.connection.on('error',() => {
error()
})
// 设置连接关闭回调
mongoose.connection.on('close',() => {
console.log('连接关闭 -----> ');
})
}
index.js
const db = require("./db/db");
const mongoose = require("mongoose");
// 调用函数
db(
() => {
console.log(" 连接成功 -----> ");
// 设置集合中的文档的属性以及属性值的类型
let BookSchema = new mongoose.Schema({
name: String,
author: String,
price: Number,
});
// 6.创建模型对象 对文档操作的封装地域性
let BoolModel = mongoose.model("books", BookSchema);
// 新增
BoolModel.create(
{
name: "西游记",
auther: "吴承恩",
price: 19.9,
},
(err, data) => {
// 判断是否有错误
if (err) {
console.log(err);
return;
}
console.log(data);
// 关闭数据库连接
mongoose.disconnect();
}
);
},
() => {
console.log(" 连接失败 -----> ");
}
);
新增其他文件做优化
config.js
module.exports={
DBHOST:'127.0.0.1',
DBPORT:27017,
DBNAME:'bilibili'
}
db
module.exports=function(success,error){
if(typeof error !=='function'){
error=() => {
console.log('连接失败 -----> ');
}
}
const mongoose=require('mongoose')
const {DBHOST,DBPORT,DBNAME}=require('../config/config')
mongoose.set('strictQuery',true)
mongoose.connect(`mongodb://${DBHOST}:${DBPORT}/${DBNAME}`)
mongoose.connection.once('open',() => {
success()
})
// 设置连接错误回调
mongoose.connection.on('error',() => {
error()
})
// 设置连接关闭回调
mongoose.connection.on('close',() => {
console.log('连接关闭 -----> ');
})
}
BookModel.js 抽离
const mongoose = require("mongoose");
let BookSchema = new mongoose.Schema({
name: String,
author: String,
price: Number,
});
let BoolModel = mongoose.model("books", BookSchema);
module.exports=BoolModel
index.js
const db = require("./db/db");
const mongoose = require("mongoose");
const BoolModel=require('./models/BookModel')
// 调用函数
db(
() => {
// 新增
BoolModel.create(
{
name: "西游记",
auther: "吴承恩",
price: 19.9,
},
(err, data) => {
// 判断是否有错误
if (err) {
console.log(err);
return;
}
console.log(data);
// 关闭数据库连接
mongoose.disconnect();
}
);
},
);
或者 新增一个电影
MovieMOdel.js
const mongoose = require("mongoose");
let MovieSchema = new mongoose.Schema({
title:String,
director:String
});
let MovieModel = mongoose.model("movie", MovieSchema);
module.exports=MovieModel
test.js
const db = require("./db/db");
const mongoose = require("mongoose");
const MovieModel=require('./models/MovieMOdel')
// 调用函数
db(
() => {
// 新增
MovieModel.create(
{
title: "让子弹飞",
director: "姜文",
},
(err, data) => {
// 判断是否有错误
if (err) {
console.log(err);
return;
}
console.log(data);
// 关闭数据库连接
mongoose.disconnect();
}
);
},
);
七、 图形化管理工具
我们可以使用图形化的管理工具来对 Mongodb 进行交互,这里演示两个图形化工具
Robo 3T 免费 github.com/Studio3T/ro…
Navicat 收费 www.navicat.com.cn/
练习:
将日期转成日期对象
下载npm i moment
导入
const moment=require('moment')
console.log(moment('2023-10-27').toDate());
使用
const AccountsModel=require('../models/AccountModel')
//新增记录
router.post('/account', (req, res) => {
// 修改req.body.time的值
AccountsModel.create({
...req.body,
time:moment(req.body.time).toDate()
},(err,data) => {
if(err){
rs.status(500).send('插入失败~~~')
return
}
//成功提醒
res.render('success', {msg: '添加成功哦~~~', url: '/account'});
})
});