github编辑

在 Node 中使用非关系型数据库 MongoDB

在 Node 中使用非关系型数据库 MongoDB

MongoDB 是非关系型数据库的一种,相比起其他数据库而言,对前端开发者更友好

一、数据库简介

  • 数据库是按照数据结构来组织、存储和管理数据的仓库

  • 我们的程序都是在内存中运行的,一旦程序运行结束或者计算机断电,程序运行的数据都会丢失

  • 所以我们就需要将一些程序运行的数据持久化到硬盘之中,以确保数据的安全性

  • 说白了,数据库就是存储数据的仓库

  • 数据库分类

    • 关系型数据库(RDBMS)

      • MySQL、Oracle、DB2、SQL Server……

      • 关系数据库中都是表

    • 非关系型数据库(No SQL Not Only SQL)

      • MongoDB、Redis……

      • 键值对数据库

      • 文档数据库 MongoDB

二、MongoDB 简介

  • MongoDB 是为快速开发互联网 Web 应用而设计的数据库系统

  • MongoDB 的设计目标是极简、灵活、作为 Web 应用栈的一部分

  • MongoDB 的数据模型是面向文档的,所谓文档是一种类似于 JSON 的结构,简单理解 MongoDB 这个数据库中存的是各种各样的 JSON(BSON)

  • 三个概念

    • 数据库(database):数据库是一个仓库,在仓库中可以存放集合

    • 集合(collection):集合类似于数组,在集合中可以存放文档

    • 文档(document):文档数据库中的最小单位,我们存储和操作的内容都是文档

  • 下载 MongoDB

  • 安装 MongoDB

    • 安装

    • 配置环境变量 D:\Program Files\MongoDB\Server\4.2\bin

    • 在 C 盘根目录下创建 data/db 文件夹

    • 打开 cmd 命令行窗口

      • 输入 mongod 启动 MongoDB 服务器

      • 32 位的初次启动需要输入 mongod --storageEngine=mmapv1

    • 再打开一个 cmd 窗口

      • 输入 mongo 连接 mongodb,出现 >

    • 其他配置命令 mongod --dbpath "D:\Program Files\MongoDB\Server\4.2\data\db --port 123"

    • 数据库

      • 服务器用来保存数据,mongod 启动

      • 客户端用来操作服务器,对数据进行增删改查的操作,mongo 来启动

      • 需要打开两个窗口,我们可以将 MongoDB 设置为系统服务,可以自动在后台启动,不需要每次都手动启动

        • C://data/ 创建 db、log 目录

        • D:\Program Files\MongoDB\Server\4.2 下添加一个配置文件 mongod.cfg,配置文件中添加内容

          systemLog:
           destination: file
           path: c:\data\log\mongod.log
          storage:
           dbPath: c:\data\db
        • 以管理员身份打开命令行窗口,输入命令 sc.exe create MongoDB binPath="\"D:\Program Files\MongoDB\Server\4.2\bin\mongod.exe\" --service --config=\"D:\Program Files\MongoDB\Server\4.2\mongod.cfg\"" DisplayName= "MongoDB" start= "auto",创建 MongoDB 服务

        • 启动 MongoDB 服务

        • 如果启动失败,则输入 sc delete MongoDB 删除服务之后,重新开始配置

三、MongoDB 的基本操作

在 MongoDB 中,数据库和集合都不需要我们手动创建,当我们创建文档时,如果文档所在的集合或数据库不存在则会自动创建数据库和集合

MongoDB

1、基本命令

  • 显示当前的所有数据库

    • show dbs

    • show databases

  • 进入到指定的数据库中

    • use 数据库名

  • db 表示的是当前所处的数据库

    • db

  • 显示数据库中所有的集合

    • show collections

2、数据库的 CRUD 操作

安装图形化工具:MongodbManagerFreeStudio-3T

向数据库中插入文档

  • db.<collection>.insert(doc) 向集合中插入一个或多个文档

当我们向集合中插入文档时,如果没有给文档指定 _id 属性,则数据库会自动为文档添加 _id,该属性用来作为文档的唯一标识,也可以自己指定,如果我们指定了,数据库就不会添加了,如果自己指定 _id 也必须确保它的唯一性

  • db.<collection>.insertOne(doc) 插入一个文档对象

  • db.<collection>.insertMany(doc) 插入多个文档对象

  • 这两个和上面的差不多,就是写开了更容易理解

注:MongoDB 中的文档的属性值也可以是一个文档,当一个文档的属性值是文档时,我们称这为内嵌文档。

MongoDB 支持直接通过内嵌文档的属性进行查询,如果要查询内嵌文档,可以通过 . 的形式来匹配。属性名必须用引号括起来

查询

  • db.<collection>.find() 查询当前集合中的所有的文档

    • find() 用来查询集合中所有符合条件的文档。在开发时,绝对不会执行不带条件的查询

    • find() 可以接受一个对象作为条件参数

      • {} 表示查询集合中所有的文档

      • {字段名:值} 查询属性是指定值的文档

        • 值还可以添加一个选项,多个条件之间使用 , 连接

        • $eq 等于

        • $gt$gte 大于、大于等于

        • $in

        • $lt$lte

        • $ne

        • $nin

        • $or

    • find() 返回的是一个数组

    • db.stus.find({}).count()返回对象个数,一般用这个;db.stus.find({}).length()

    • db.stus.find().limit(10) 设置显示数据的上限,这里表示只显示前十条数据

    • db.numbers.find().skip(10).limit(10) skip()用于跳过指定数量的数据,这里会显示第11~20条数据。MongoDB 会自动调整 skip 和 limit 的位置,因此顺序随便

  • db.<collectin>.findOne() 查询当前集合中符合条件的第一个文档

    • findOne() 返回的是一个文档对象

修改

  • db.<collectin>.update(查询条件,新对象[,配置选项])

    • update()默认情况下回使用新对象来替换旧的对象

    • 如果需要修改指定的属性,而不是替换,需要使用“修改操作符”来完成修改

      • $set 可以用来修改文档中的指定属性

      • $push用于向数据中添加一个新的元素

      • $addT0Set向数据中添加一个新元素,如果数组中已经存在该元素,则不会添加

      • $unset 可以用来删除文档的指定属性

    • update()默认只会修改一个

  • db.<collectin>.updateMany(查询条件,新对象) 同时修改多个符合条件的文档

  • db.<collectin>.updateOne(查询条件,新对象) 修改一个符合条件的文档

  • db.<collectin>.replace(查询条件,新对象) 替换一个文档

  • 这三个也是将第一个分开了

删除

  • db.<collectin>.remove()

    • remove()可以根据条件来删除文档,传递的条件的方式和find()一样

    • 删除符合条件的所有的文档,默认会删除多个

    • 如果remove()第二个参数传递一个true,则只会删除一个

    • 如果只传递一个空对象,则会删除所有的

  • db.<collectin>.deleteOne()

  • db.<collectin>.deleteMany()

  • db.collection.drop() 删除集合

  • db.dropDatabase()删除数据库

  • 一般数据库中的数据都不会删除,所以删除的方法很少调用,一般在数据中添加一个字段,来表示数据是否被删除

四、文档之间的关系

一对一(One to One)

  • 夫妻(一个丈夫对应一个妻子)

  • 在 MongoDB 中,可以通过内嵌文档的形式来体现出一对一的关系

一对多(One to Many)/多对一(Many to One)

  • 父母——孩子、用户——订单、文章——评论

  • 也可以通过内嵌文档来映射一对多的关系,属性变为数组

多对多(Many to Many)

  • 分类——商品、老师——学生

  • 学生属于多个老师、老师教多个学生,学生中有一个老师的id,id多个用数组

五、sort 和投影

  • db.emp.find() 查询文档时,默认情况是按照 _id 的值进行排列(升序)

  • db.emp.find({}).sort({sal:1}) sort() 可以用来指定文档的排序的规则,sort() 需要传递一个队形来指定排序的规则

    • 1 表示升序

    • -1 表示降序

    • db.emp.find({}).sort(sal:1, empno:-1) 先按照 sal 升序排列,如果 sal 相同,按照 empno 降序排列

  • 注:limit、skip、sort 书写顺序没有要求

  • db.emp.find({}, {ename:1})在查询时,可以在第二个参数的位置来设置查询结果的投影 db.emp.find({}, {ename: 1, _id: 0, sal: 1})

六、Mongoose 简介

1、简介

  • 之前我们都是通过 shell 来完成对数据库的各种操作的,在开发中大部分的时候我们都需要通过程序来完成对数据库的操作

  • Mongoose 就是一个让我们可以通过 Node 来操作 MongoDB 的模块

  • Mongoose 是一个对象文档模型(ODM)库,它对 Node 原生的 MongoDB 模块进行了进一步的优化封装,并提供了很多的功能

  • 在大多数情况下,它被用来把结构化的模式应用到一个 MongoDB 集合,并提供了验证和类型转换等好处

2、Mongoose 好处

  • 可以为文档创建一个模式结构(Schema) ——约束

  • 可以对模型中的对象/文档进行验证

  • 数据可以通过类型转换转为对象模型

  • 可以使用中间件来应用业务逻辑挂钩

  • 比 Node 原生的 MongoDB 驱动更容易

3、新的对象

  • Schema(模式对象)

    • 定义约束了数据库中的文档结构

  • Model

    • Model 对象作为集合中所有文档的表示,相当于 MongoDB 数据库中的集合

  • Document

    • Document 表示集合中的具体文档,相当于集合中的一个具体的文档

七、连接 MongoDB 数据库

  1. 下载安装 Mongoose npm i mongoose --save

  2. 在项目中引入 Mongoose var mongoose = require("mongoose")

  3. 连接数据库 mongoose.connect('mongodb://数据库IP地址:端口号/数据库名');

    • 端口号如果是默认端口号(27017),则可以省略不写

  4. [可选] 监听 MongoDB 数据库的连接状态

    • 在 Mongoose 对象中,有一个属性叫做 connection,该对象表示的就是数据库连接通过监视该对象的状态,可以来监听数据库的连接与断开

      • mongoose.connection.once("open",function(){}) 数据库连接成功的事件

      • mongoose.connection.once("close",function(){}) 数据库断开的事件

  5. 断开数据库连接(一般不需要调用) mongoose.disconnect()

    • MongoDB 数据库,一般情况下只需要连接一次,连接一次以后,除非项目停止、服务器关闭,否接连接一般不会断开

八、Schema、Model 和 Document

有了 Model,就可以对数据库进行增删改查的操作了

  • Model.crate(doc(s), [callback])

    • 用来创建一个文档并添加到数据库中

    • doc(s) 可以是一个文档对象,也可以是一个文档对象的数组

    • callback 当操作完成之后调用的回调函数

  • 查询

    • Model.find(conditions, [projection], [options], [callback]) 查询所有符合条件的文档 总会返回一个数组

    • Model.findById(id, [projection], options), [callback] 根据文档的 id 属性查询文档

    • Model.findOne([conditions], [projection], [options], [callback]) 查询符合条件的第一个文档 总会返回一个具体的对象

      • conditions 查询的条件

      • projection 投影 需要获取到的字段 两种方式

        • {} 对象,要的字段为 1,不要的为0

        • "" 字段名、不要的设为 -

      • options 查询选项(skip limit)

      • callback 回调函数,查询结果会通过回调函数返回,毁掉函数必须传,如果不传回调函数,压根不会查询

    • 通过 find() 查询的结果,返回的对象,就是 Document,文档对象

  • 修改

    • Model.update(conditions, doc, [options], [callback])

    • Model.updateMany(conditions, doc, [options], [callback])

    • Model.updateOne(conditions, doc, [options], [callback])

      • 用来修改一个或多个文档

      • conditions 查询条件

      • doc 修改后的对象

      • options 配置参数

      • callback 回调函数

    • Model.replaceOne(conditions, doc, [options], [callback]) 替换

  • 删除(不用这个)

    • Model.remove(conditions, [callback])

    • Model.deleteOne(conditions, [callback])

    • Model.deleteMany(conditions, [callback])

  • Model.count(conditions, [callback])

    • 统计文档的数量

Document 和集合中的文档一一对应,Document 是 Model 的实例,通过 Model 查询到结果都是 Document

Document 的方法

  • Model#save([options], [options.safe], [options.validateBeforeSave], [fn])

  • update(update, [options], [callback])

    • 修改对象

  • remove([callback])

    • 删除对象(拒绝用这个)

  • get(name)

    • 获取文档中的指定属性值

  • set(name, value)

    • 设置文档的指定的属性值

  • id

    • 获取文档的 _id 属性值

  • toJSON()

    • 转换为一个 JSON 对象

  • toObject()

    • 将 Document 对象转换为普通的 js 对象

    • 转换为普通的 js 对象以后,所有的 Document 对象的方法或属性都不能使用了

  • 其他 equals(doc) isNew isInit(path)

九、Mongoose 的模块化

定义一个模块,用来连接 MongoDB 数据库

定义一个 student 的模型,几个模型就可以创建几个 js 文件

其他地方引入

练习

最后更新于