跳至主要內容

02.MongoDB的学习之路

pinia原创大约 9 分钟MongoDBMongoDB

一、MongoDB 介绍

1.1 概念

1.2 数据库

  • 数据库(DataBase)是按照数据结构来组织、存储和管理数据的 应用程序

  • 数据库的主要作用就是 管理数据,对数据进行 增(c)、删(d)、改(u)、查(r)

  • 相比于纯文件管理数据,数据库管理数据有如下特点:

    1. 速度更快
    2. 扩展性更强
    3. 安全性更强
  • Mongodb 的操作语法与 JavaScript 类似,容易上手,学习成本低

二、MongoDB 核心概念

  • Mongodb 中有三个重要概念需要掌握
    • 数据库(database) 数据库是一个数据仓库,数据库服务下可以创建很多数据库,数据库中可以存放很多集合
    • 集合(collection) 集合类似于 JS 中的数组,在集合中可以存放很多文档
    • 文档(document) 文档是数据库中的最小单位,类似于 JS 中的对象
mongodb
mongodb
  • 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 文件中的 一级属性的数组值 好比是 集合

    • 数组中的对象好比是 文档

    • 对象中的属性有时也称之为 字段

一般情况下

  • 一个项目使用一个数据库
  • 一个集合会存储同一种类型的数据

三、MongoDB 下载与安装

  • 下载地址: https://www.mongodb.com/try/download/communityopen in new window
  • 建议选择 zip 类型, 通用性更强
  • 配置步骤如下:
    1. 将压缩包移动到 D:\Program Files 下,然后解压
    2. 创建 D:\data\db 目录,mongodb 会将数据默认保存在这个文件夹
    3. 以 mongodb 中 bin 目录作为工作目录,启动命令行
    4. 运行命令 mongod,看到最后的 waiting for connections 则表明服务 已经启动成功
    5. 再打开一个命令行mongo,连接本机的 mongodb 服务

注意

  1. 为了方便后续方便使用 mongod 命令,可以将 bin 目录配置到环境变量 Path 中
  2. 千万不要选中服务端窗口的内容,选中会停止服务,可以 敲回车 取消选中

四、MongoDB 命令行交互

4.1数据库命令

  1. 显示所有的数据库

    show dbs
    
  2. 切换到指定的数据库,如果数据库不存在会自动创建数据库

    use 数据库名
    
  3. 显示当前所在的数据库

    db
    
  4. 删除当前数据库

    use 数据库名 //切换至需要删除的库下
    db.dropDatabase()
    

4.2集合命令

  1. 创建集合

    db.createCollection('集合名称')
    
  2. 显示当前数据库中的所有集合

    show collections
    
  3. 删除某个集合

    db.集合名.drop()
    
  4. 重命名集合

    db.集合名.renameCollection('newName')
    

4.3文档命令

  1. 插入文档

    db.集合名.insert(文档对象);
    
  2. 查询文档

    db.集合名.find(查询条件)
    

    _id 是 mongodb 自动生成的唯一编号,用来唯一标识文档

  3. 更新文档

    db.集合名.update(查询条件,新的文档)
    db.集合名.update({name:'张三'},{$set:{age:19}})
    
  4. 删除文档

    db.集合名.remove(查询条件)
    

4.4 应用场景

4.4.1新增

  • 用户注册
  • 发布视频
  • 发布商品
  • 发朋友圈
  • 发评论
  • 发微博
  • 发弹幕
  • .......

4.4.2删除

  • 删除评论
  • 删除商品
  • 删除文章
  • 删除视频
  • 删除微博
  • ......

4.4.3更新

  • 更新个人信息
  • 修改商品价格
  • 修改文章内容
  • ......

4.4.4查询

  • 商品列表
  • 视频列表
  • 朋友圈列表
  • 微博列表
  • 搜索功能
  • ......

五、Mongoose

5.1 mongoose 介绍

5.2 mongoose使用流程

  1. 安装
npm
npm install mongoose
  1. 使用
//导入mongoose
const mongoose = require('mongoose');
//连接数据库
mongoose.connect('mongodb://127.0.0.1:27017/bilibili', {useNewUrlParser: true, useUnifiedTopology: true});//bilibili是数据库名 27017是端口号 {useNewUrlParser: true, useUnifiedTopology: true }是固定写法   useNewUrlParser: true, useUnifiedTopology: true 是为了解决警告
//设置回调
mongoose.connection.once('open', () => {
    console.log('数据库连接成功');
    //创建Schema对象 定义文档结构 用来约束集合的
    let bookSchema = new mongoose.Schema({
        bookName: {
            type: String,
            required: true,//必填项
            unique: true,//唯一
            default:'三国演义',//默认值
            enum:['三国演义','水浒传','红楼梦']//枚举
        },
        author: String,
        age: Number,
        is_hot: Boolean,
        tags: [String],
        public_date: Date,
        text:mongoose.Schema.Types.Mixed//混合类型
    })
    //创建model对象 用来操作数据库 用来对数据库进行增删改查 mongoose会自动将集合名变成复数
    let bookModel = mongoose.model('books', bookSchema);//book是集合名 teacherSchema是约束
    //创建文档
    bookModel.create({
        bookName: '三国演义',
        author: '罗贯中',
        age: 50,
        is_hot: true,
        tags: ['小说', '名著'],
        public_date: new Date()
    }).then(data => {
        console.log(data);
        mongoose.disconnect();//断开连接,项目中不需要断开连接
    }).catch(err => {
        console.log(err);
    })
    //删除单个文档
    // bookModel.deleteOne({bookName:'三国演义'}).then(data=>{
    //     console.log(data);
    // }).catch(err=>{
    //     console.log(err);
    // })
    // //删除多个文档
    // bookModel.deleteMany({bookName:'三国演义'}).then(data=>{
    //     console.log(data);
    // }).then(err=>{
    //     console.log(err);
    // })
    // //修改单个文档
    // bookModel.updateOne({bookName:'三国演义'},{age:100}).then(data=>{}).catch(err=>{})
    // //修改多个文档
    // bookModel.updateMany({bookName:'三国演义'},{age:100}).then(data=>{}).catch(err=>{})
    // //查询单个文档
    // bookModel.findOne({bookName:'三国演义'}).then(data=>{}).catch(err=>{})
    // //查询多个文档
    // bookModel.find({bookName:'三国演义'}).then(data=>{}).catch(err=>{})
    // //查询所有文档
    // bookModel.find().then(data=>{}).catch(err=>{})
})//success once只执行一次 官方推介使用once
mongoose.connection.on('error', () => {
    console.log('数据库连接失败');
})//error
mongoose.connection.on('close', () => {
    console.log('数据库连接断开');
})//close

5.3 mongoose字段类型

文档结构可选的常用字段类型列表

类型描述
String字符串
Number数字
Boolean布尔值
Array数组,也可以使用 [] 来标识
Date日期
BufferBuffer 对象
Mixed任意类型,需要使用 mongoose.Schema.Types.Mixed 指定
ObjectId对象 ID,需要使用 mongoose.Schema.Types.ObjectId 指定
Decimal128高精度数字,需要使用 mongoose.Schema.Types.Decimal128 指定

5.4 字段值验证

Mongoose 有一些内建验证器,可以对字段值进行验证

5.4.1必填项

title: {
	type: String,
 	required: true // 设置必填项
},

5.4.2默认值

author: {
 	type: String,
 	default: '匿名' //默认值
},

5.4.3枚举值

gender: {
	type: String,
	enum: ['男','女'] //设置的值必须是数组中的
},

5.4.4唯一值

username: {
	type: String,
 	unique: true
},

注意

  1. unique 需要 重建集合 才能有效果

  2. 永远不要相信用户的输入

5.5 mongoose 的CRUD

//新建文档
bookModel.create({}).then(data=>{}).catch(err=>{})
//批量新建文档
bookModel.insertMany([{},{},{}]).then(data=>{}).catch(err=>{})
    

//查询单个文档
bookModel.findOne({bookName:'三国演义'}).then(data=>{}).catch(err=>{})
//查询多个文档
bookModel.find({bookName:'三国演义'}).then(data=>{}).catch(err=>{})
//根据id查询文档
bookModel.findById('5f0b9b9b6b9b6c1f0c8b9b6b').then(data=>{}).catch(err=>{})
//查询所有文档
bookModel.find().then(data=>{}).catch(err=>{})


//修改单个文档
bookModel.updateOne({bookName:'三国演义'},{age:100}).then(data=>{}).catch(err=>{})
//修改多个文档
 bookModel.updateMany({bookName:'三国演义'},{age:100}).then(data=>{}).catch(err=>{})


//删除单个文档
bookModel.deleteOne({bookName:'三国演义'}).then(data=>{}).catch(err=>{})
//删除多个文档
bookModel.deleteMany({bookName:'三国演义'}).then(data=>{}.catch(err=>{})

5.6 mongoose条件控制

5.6.1运算符

在 mongodb 不能 > < >= <= !== 等运算符,需要使用替代符号

  • >使用 $gt
  • < 使用 $lt
  • = 使用 $gte
  • <= 使用 $lte
  • !== 使用 $ne
db.students.find({id:{$gt:3}}); id号比3大的所有的记录

// 价格小于 20 的图书
BookModel.find({ price: { $lt: 20 } }, (err, data) => {
	if (err) {
		console.log('读取失败~~~')
		return
    }
    console.log(data)
})

5.6.2逻辑运算

$or 逻辑或的情况

db.students.find({$or:[{age:18},{age:24}]});

// 曹雪芹 或者 余华的书
BookModel.find({ $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
BookModel.find({ $and: [{ price: { $gt: 30 } }, { price: { $lt: 70 } }] }, (err, data) => {
    if (err) {
      console.log('读取失败~~~')
      return
    }
    console.log(data)
})

5.6.3正则匹配

条件中可以直接使用 JS 的正则语法,通过正则可以进行模糊查询

db.students.find({name:/imissyou/});

正则表达式,搜索书籍名称中带有 '三' 的图书
BookModel.find({ name: /三/ }, (err, data) => {
	if (err) {
		console.log('读取失败~~~')
      	return
	}
   console.log(data)
})

BookModel.find({ name: new RegExp('三') }, (err, data) => {
 	if (err) {
      	console.log('读取失败~~~')
      	return
    }
    console.log(data)
})

5.7 个性化读取

5.7.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.7.2数据排序

// sort 排序
// 1:升序
// -1:倒序
SongModel.find().sort({hot:1}).exec(function(err,data){
	if(err) throw err;
	console.log(data);
	mongoose.connection.close();
});

5.7.3数据截取

//skip 跳过   limit 限定
SongModel.find().skip(10).limit(10).exec(function(err,data){
	if(err) throw err;
	console.log(data);
	mongoose.connection.close();
});

5.8 mongoose的模块化

1.新建db文件夹:

  1. 然后新建配置文件config.js

  2. 然后新建db.js模块文件

  3. 然后新建Module文件夹,,里面放着module 模型对象

  4. 使用

  5. config.js

//配置文件
module.exports = {
    DBAGREEMENT:'mongodb://',
    DBHOST: '127.0.0.1',
    DBPORT: 27017,
    DBNAME: 'bilibili'
}
  1. 写db.js模块
/**
 * 连接数据库
 * @param success 成功回调
 * @param error 失败回调
 * @param close 关闭回调
 */
module.exports = (success, error, close) => {
    //导入mongoose
    const mongoose = require('mongoose');
     //导入配置文件
    const{DBAGREEMENT, DBHOST, DBPORT, DBNAME} = require('./config');
    //连接数据库
    mongoose.connect(`${DBAGREEMENT}${DBHOST}:${DBPORT}/${DBNAME}`, {useNewUrlParser: true, useUnifiedTopology: true});//bilibili是数据库名 27017是端口号 {useNewUrlParser: true, useUnifiedTopology: true }是固定写法   useNewUrlParser: true, useUnifiedTopology: true 是为了解决警告
    // 设置strictQuery为true
    mongoose.set('strictQuery', true);//为了解决警告
    //设置回调
    mongoose.connection.once('open', () => {
        success();
    });
    mongoose.connection.on('error', () => {
        error();
    });
    mongoose.connection.on('close', () => {
        close();
    });
}
  1. module文件
//导入mongoose
const mongoose = require('mongoose');
//创建模型对象
let userSchema = new mongoose.Schema({
    name: String,
    age: Number,
})
//创建数据模型
let userModel = mongoose.model('user', userSchema);
//导出数据模型
module.exports = userModel;
  1. 使用db.js模块
const db = require('./db/db');
const userModel = require('./db/module/userModule');
db(() => {
    //创建文档对象
    userModel.create({
        name: '李四',
        age: 20
    }).then((data) => {
        console.log(data);

    }).catch((err) => {
        console.log(err);
    })
}, () => {
    console.log('数据库连接失败');
}, () => {
    console.log('数据库连接断开');
})

六、图形化管理工具

我们可以使用图形化的管理工具来对 Mongodb 进行交互,这里演示两个图形化工具

上次编辑于:
贡献者: 林深不见鹿