MongoDB 简介
MongoDB 是一个基于分布式文件存储的数据库(DataBase),官方网站是www.mongodb.com。
-
数据库(DataBase)
- 数据库本质上就是应用程序,也就是软件
- 它按照数据结构来组织、存储和管理数据
- 主要作用就是管理数据 ,对数据进行 增(c)、删(d)、改(u)、查(r)操作
-
使用 Ajax 操作 JSON 文件也可以对数据进行管理,为何还要使用数据库?
-
数据库管理数据的特点
相比于纯文件管理数据,数据库管理数据很多优势
-
-
MongoDB 数据库与其他数据库的区别
MongoDB 核心概念
Mongodb 中有几个重要概念
-
数据库(DataBase)
- 数据库是一个数据仓库,数据库服务下可以创建很多数据仓库,数据仓库中可以存放很多集合
- 因为在一台网站服务器中可以放置多个网站应用,每个网站应用都需要一个独立的数据仓库,我们只需安装一个数据库软件,就可以在内部建立多个数据仓库
-
集合(collection)
- 集合,就是具有同一类特征的数据组合成的数据集,如用户信息与商品信息存储在不同的集合中
- 在数据仓库内部,可以建立多个集合
- 集合类似于 JS 中的数组,在集合中可以存放很多文档
-
文档(document)
- 文档,就是具体的一条条的数据,在数据库中就是一条条 JSON 格式的对象
- 在集合内部,可以有多个文档
- 文档是数据库中用于存储的最小单位,类似于 JS 中的对象
-
字段(field)
- 字段,就是文档中的属性名
- JSON 格式对象的内部,存在很多属性,数据库中将 JSON 格式对象的属性叫做字段。比如
"name":"张三" "age":18
等等,类比 JS 中的对象属性
在数据库软件中可以包含多个数据仓库,在每个数据仓库中可以包含多个数据集合,每个数据集合中可以包含多条文档 (具体的数据),每条文档中可以存在多个字段
类比JSON文件如:
{
"users": [
{
"uname": "zhangsan",
"password": "zs123456",
"id": 1
},
{
"uname": "lisi",
"password": "666",
"email": "dz@166.com",
"id": 2
},
{
"uname": "666",
"password": "666",
"email": "dz@166.com",
"id": 3
}
],
"comments": [
{
"uname": "小郭",
"comment": "我爹是郭巨侠",
"time": "2012-03-15 14:32:35",
"id": 1
},
{
"uname": "jack",
"comment": "十多个三国杀",
"time": "2023-04-21 09:43:24",
"id": 8
},
{
"uname": "张三",
"comment": "王侯将相宁有种乎!",
"time": "2023/05/06 14:34:30",
"id": 9
}
]
}
可以通过类比 JSON 文件来理解一下 MongoDB 中的概念
- 一个 JSON 文件就像一个数据库,MongoDB 服务中可以存在 N 个数据库
- JSON 文件中的接口就像数据库中的一个个集合,每个数据库中可以存在多个集合
- 接口数组中保存的一条条对象类型的数据就好比数据库中的文档,每个文档中可以存在多个字段
- 对象中存放的一个个属性就好比数据库中的字段,每个字段要有指定的类型
一般来说一个项目中只会使用一个数据库;在同一个集合中会存储具有同一类特征的数据
MongoDB 的下载安装
可以在 www.mongodb.com/try/downloa…这个地址中,下载社区版的MongoDB数据库
版本区别(了解)
- alpha - 内测版 - 开发团队内部检测bug使用,不建议使用
- beta - 公测版 - 面向公众的测试版本,可能存在bug,不建议使用
- pre - 先行版 - 与alpha版本类似,不建议使用
- RC(release candidate) - 候选版 - 不建议使用
- release - 发行版 - 官方推荐使用版本,一般不会后面写这个标识
- stable - 稳定版 - 相比其他版本来说bug较少,最为稳定,也是开发中最常使用的版本
- current或lastest - 尝鲜版(最新版) - 可能存在大量的bug,运行时不稳定,不建议使用
下载时,建议使用5.0.17 版本 ,选择zip类型进行下载,使用更加方便
服务器配置
-
将MongoDB压缩版解压到除C盘外的任意目录中
-
在文件解压的那个盘的根目录下,创建data文件夹,然后在data 文件夹中创建db文件夹,如当前将MongoDB解压到了D盘,就要创建
D:/data/db
目录,MongoDB会将数据默认保存在这个文件夹 -
以MongoDB文件的bin目录作为工作目录,打开cmd
-
输入
mongod
命令,它会自动执行当前文件夹下的mongod.exe文件,这是MongoDB的服务器运行程序看到信息中出现wating for connections... 等信息,就表示数据库服务已经开启成功,下一步就可以使用客户端来链接数据库服务了
一般不要选中数据库服务端窗口中的内容,选中时可能会停止提供服务,一旦选中可以使用回车键取消选中
-
打开一个新的cmd,注意不要关闭之前开启的数据库服务,输入
mongo
命令,它会自动执行当前文件夹下的mongo.exe文件,这是MongoDB的客户端运行程序 -
配置环境变量
为了便于以后使用MongoDB命令更方便,我们使用将MongoDB的bin目录配置到环境变量path中
1. 查看电脑属性 找到此电脑右键
2. 进行高级系统设置,查看环境变量
3. 在系统变量中找到path变量并选中,点击编辑
4. 在编辑环境变量中点击新建,填入MongoDB的bin目录的绝对路径,并确定保存即可
MongoDB常用命令(了解)
一般来说,学习数据库都需要使用一些常用的数据库命令,后面学习图形化界面操作以后使用较少,所以了解一些常用的即可
数据库命令
-
显示所有数据库
show dbs
-
切换到指定数据库,如果数据库不存在,会自动帮我们创建数据库
use 数据库名
-
显示当前所在数据库
db
-
删除当前数据库
use 数据库名 db.dropDatabase()
集合命令
-
创建集合
db.createCollection("集合名")
-
显示当前数据库中的所有集合
show collections
-
删除某个集合
db.集合名.drop()
-
给集合改名
db.集合名.renameCollection("集合的新名字")
文档命令
-
插入文档
db.集合名.insert(文档对象)
-
查询文档
db.集合名.find(指定条件)
-
更新文档
db.集合名.update(指定条件,新文档)
db.集合名.updata({age:18},{$set:{age:36}})
更新文档是直接以一个新文档的形式来替换旧文档的,所以如果不使用$set:{}这种形式来替换指定字段的数据,很容易造成其他数据丢失
-
删除文档
db.集合名.remove(指定条件)
_id 是我们MongoDB数据库中自动生成的唯一编码,用来作为文档的唯一标识
应用场景
新增
- 新用户的注册
- 信息发布(发朋友圈、抖音动态等等)
- 内容评论
- 弹幕发送等等
- 添加购物车
- ..........
删除
- 删除购物车
- 删除发布的动态
- 删除评论
- 删除文档等等
- ............
在一些项目中不会真的把指定的数据从数据库中进行删除,而是做了一些伪删除处理(就是不从数据库中真的删除数据,而是在其内部添加一条特定的属性,如
is_deleted:true
,当值为true时,在检索时会忽略此数据,说明这项数据已经被做出删除处理,反之(值为false)说明数据正常)
更新
- 更新个人信息
- 修改商品价格
- 修改动态
- ...........
查询
查询功能是我们使用最多的,查询在应用程序中无处不在
- 信息列表
- 商品列表
- 动态列表
- 搜索引擎搜索
- ..............
mongoose
mongoose简介
面向node.js来更优雅的创建MongoDB对象模型
使用命令行操作数据库,来完成一个项目中所有与数据相关的功能,显然是不可行的,因为编写MongoDB验证、转换和业务逻辑是非常麻烦的,所以诞生了mongoose。Mongoose 是一个对象文档模型库
mongoose的作用
Mongoose提供了一种直接的、基于文档类型规则模式结构的数据库建模解决方案,而且它还包含数据类型转换、验证,查询构建,业务逻辑钩子等功能,开箱即用。让我们可以在node.js中使用代码操作 mongodb 数据库。
mongoose使用
-
安装 mongoose 模块
npm i mongoose
-
导入mongoose模块
const mongoose = require('mongoose')
-
使用mongoose模块提供的connect方法,连接指定的数据库
// 参数就是我们要链接的数据库名称 如果这个数据库不存在,它会帮我们自动创建 mongoose.connect("mongodb://127.0.0.1:27017/weibo")
-
设置连接回调,进行事件监听
// 让我们可以在连接成功、连接失败、关闭连接等事件发生时,进行一些事件处理 // 监听连接成功事件 mongoose.connection.on("open", () => { console.log("connect the db is ok"); }) // 监听连接失败事件 mongoose.connection.on("error", () => { console.log("open a lots of error"); }) // 监听连接关闭事件 mongoose.connection.on("close", () => { console.log("close the db"); })
监听连接成功事件时,也可以使用once方法
mongoose.connection.once("open", () => { console.log("connect the db is ok"); })
-
once与on的区别
-
当数据库服务掉线时,mongoose会尝试重新连接,重连成功以后
- 如果使用once,callback不会再重新执行
- 如果使用on,callback会重新执行
-
官方推荐使用once,因为在open事件中一般要写入大量的执行代码
- 如在其中写入了
app.listen(80)
,这个代码只会执行一次,当多次执行时肯定是无效的,且会报错
- 如在其中写入了
-
使用node运行JavaScript文件时,如果出现关于 { useNewUrlParser: true } 与 { useUnifiedTopology: true } 的警告提示信息,可以根据提示按下列方式处理
-
在connect参数中写入参数
{ useNewUrlParser: true, useUnifiedTopology: true }
- seNewUrlParser 使用新的解析器
- useUnifiedTopology 使用新的服务器发现和监控引擎
mongoose.connect("mongodb://127.0.0.1:27017/cilicili", { useNewUrlParser: true, useUnifiedTopology: true })
-
-
当数据库连接成功后,在其回调函数内部创建集合对象,并定义文档结构(属性名、属性值的数据类型等)
// 设定集合规则 const BookSchema = new mongoose.Schema( // 定义文档的数据结构 // 创建文档的属性名及属性值的类型 { name: String, author: String, price: Number, time: Date } )
-
创建文档模型对象(集合)并应用规则
// 创建模型对象 // 让创建的对象使用我们定义好的文档结构规则 const BookModel = mongoose.model("Book", BookSchema)
-
创建文档(新增)
-
方法1,创建实例对象
const xiyou = new BookModel( // 参数就是要插入的数据 { name: "西游记", author: "吴承恩", price: 36.8, time: new Date() } // 数据库会自动帮助我们创建一个_id值 // _v是版本值,一般用不到 ) console.log(xiyou);
-
方法2,使用异步函数创建
BookModel.create( // 参数就是要插入的数据 { name: "石头记", author: "曹雪芹", price: 26.5, time: new Date() } ) .then(data => { // 操作成功,显示新增的数据 console.log(data); }) .catch(err => { // 操作失败,抛出错误信息 throw err })
-
-
操作数据库成功后,及时关闭连接,减少性能消耗
// 养成操作完数据就关闭连接的好习惯 mongoose.disconnect()
字段类型的说明(了解)
类型 | 说明 |
---|---|
String | 字符串类型,常用于文本等内容 |
Number | 数值型,常用于数量、价格、年龄等内容 |
Boolean | 布尔类型 |
Array | 数组,也可以使用[ ]来表示,用于一组数据 |
Date | 日期 |
Buffer | Buffer对象中存储的是二进制的数据流【可用于存储图片、音频、视频等,但是使用的不多,因为这些资源一般都被存放到静态资源文件夹中,然后将其路径处理为url交给数据库进行保存了,只需使用对应url就能访问到这些资源】 |
ObjectId | 对象Id,需要使用mongoose.Schema.Types.ObjectId 指定数据类型,这个值必须是文档的Id值,一般用来外键使用【外键就是,将另一个文档中的Id存放在此文档中,让另一个文档与当前文档进行关联,当我们需要调用另一个文档中的数据时,可以通过这个Id直接调取,多使用在联合查询中】 |
Mixed | 任意类型,就是不限制数据类型,需要mongoose.Schema.Types.Mixed指定数据类型 |
Decimal | 高精度数字,需要使用mongoose.Schema.Types.Decimal128 指定数据类型,当数据需要较高数字精度时使用 |
字段验证
在创建集合规则时,可以设置当前字段的验证规则,对新增文档中的属性值进行验证
-
验证成功将让其进入进行存储
-
验证失败就会输出插入失败并拒绝进行存储
-
验证规则
-
required: true 必填字段
-
minlength:3 字符串最小长度为3
-
maxlength: 20 字符串最大长度为20
-
min: 2 数值最小为2
-
max: 100 数值最大为100
-
enum: ['html', 'css', 'javascript', 'node.js'] 枚举值
-
trim: true 去除字符串两边的空格
-
validate: 自定义验证器
-
default: 默认值
-
unique: true 唯一值
- 唯一值需要重新创建集合才会生效
- 用户输入的数据类型用于不可靠
-
-
获取错误信息
error.errors['字段名称'].message
数据库常用操作
常用操作无非是增(create)删(delete)改(update)查(find)
新增
-
添加单条文档
文档模型对象.create(文档).then(处理新增成功的语句).catch(处理添加失败的语句)
BookModel.create( // 参数就是要插入的数据 { name: "石头记", author: "曹雪芹", price: 26.5, time: new Date() } ) .then(data => { // 操作成功,显示新增的数据 console.log(data); // 8. 关闭数据库链接 // 养成操作完数据就关闭连接的好习惯 mongoose.disconnect() }) .catch(err => { // 操作失败,抛出错误信息 throw err })
-
添加多条文档
文档模型对象.inserMany([文档]).then(处理新增成功的语句).catch(处理添加失败的语句)
BookModel.insertMany( [ { name: "葫芦娃", author: "小金刚", price: 29.8, time: new Date(), is_hot: true, type: ["传说"], language: "英语" }, { name: "三毛流浪记", author: "失名", price: 29.8, time: new Date(), is_hot: true, type: ["历史"], language: "英语" } ] ).then(data => { console.log(data); console.log(1); }) .catch(err => { throw err })
删除
-
删除单条文档
文档模型对象.deleteOne(指定的唯一条件).then(处理成功的语句).catch(处理失败的语句)
BookModel.deleteOne({ _id: "645b5c955280cf50e895e21e" }) .then(() => { console.log("删除成功"); }) .catch(() => { console.log("删除失败"); })
-
删除多条文档
文档模型对象.deleteMany(指定条件).then(处理成功的语句).catch(处理失败的语句)
BookModel.deleteMany({ name: "三国演义1998" }) .then(() => { console.log("删除成功"); }) .catch(() => { console.log("删除失败"); })
更新
-
更新单条文档
文档模型对象.updateOne(指定的唯一条件).then(处理成功的语句).catch(处理失败的语句)
BookModel.updateOne({ _id: "645b515f5aabc42dbcbdf138" }, { name: "国家分裂为3股势力斗争的爱恨情仇" }) .then(() => { console.log("更新成功"); }) .catch(() => { console.log("更新失败"); })
-
更新多条文档
文档模型对象.updateMany(指定条件).then(处理成功的语句).catch(处理失败的语句)
BookModel.updateMany({ author: "罗贯中" }, { price: 9.9 }) .then(() => { console.log("更新成功"); }) .catch(() => { console.log("更新失败"); })
查询
-
查询单条文档
文档模型对象.findOne(指定的唯一条件).then(处理成功的语句).catch(处理添加失败的语句)
BookModel.findOne({ _id: "645b515f5aabc42dbcbdf138" }) .then((data) => { console.log(data); }) .catch(() => { console.log("查询失败"); })
-
通过id查询文档
文档模型对象.findById(Id值).then(处理成功的语句).catch(处理添加失败的语句)
BookModel.findById("645b515f5aabc42dbcbdf138") .then((data) => { console.log(data); }) .catch(() => { console.log("查询失败"); })
-
查询所有的文档
文档模型对象.find().then(处理成功的语句).catch(处理添加失败的语句)
// 如果参数为空,会查询所有的数据 BookModel.find() .then((data) => { console.log(data); }) .catch(() => { console.log("查询失败"); })
-
查询多条文档
文档模型对象.find().then(指定条件).catch(处理添加失败的语句)
// 如果写入参数,参数为指定的条件
BookModel.find({ name: "三国演义" })
.then((data) => {
console.log(data);
})
.catch(() => {
console.log("查询失败");
})
本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。
在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。
本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。
除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。
在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!