mongoose 再认识(一)

缘自世界

mongoose 是一个ODM(Object Data Model)的库,也叫做对象数据模型。那么为什么说是对象数据模型呢?

注:MongoDB或者Mongo是NoSQL类型的数据库,也就是说是非关系型的数据库。

它被用来处理数据,实现对象间的转换。

  • 数据处理:创建一个Schema,提供Schema的数据验证功能。
  • 对象的转换:这些对象是指开发过程中创建的对象和MongodDB中代表的相应对象。

如果不明白,或者似懂非懂,如果看了下文,相信你会明白不少。

常用的术语

Collections

Mongo中的Collections相当于关系数据库中的表(tables),它包含了大量的JSON文档(document)。

Documents

Documents相当于SQL中的记录(records)或者(rows)。在SQL中需要用多个表,通过数据间的引用来表达数据间的关联,但是在Mongo中可以通过一个Document来实现。

NoSQL的Documents VS SQL 中的关联Tables

Schema

SQL定义一个schema通过表(table)的定义,而MongoDB中是没有这个的,如果我们使用MongoDB直接插入的就是一个document。mongoose它定义了一个schema来表示document 的数据结构或者构造函数,它是建立在应用层面上的,每个docuemnt都是它的示例对象。

Fields

Fields 或者称之为属性,它相当于SQL中的(columns),它用来形成一个个schema

Models

Schema一样它也是一个数据结构或者构造函数,不过它更特殊。它使用schema创建了一个Document的实例,这个实例相当于SQL中的记录(record)。

mongoose中的 Schema 和 Model

mongoose中的schemadocument的构造函数,使用它可以定义一个document的默认值,进行字段(fields)的验证。

mongoose中的model提供了一个访问数据的接口,通过它可以实现对document(也可以叫做记录)的CRUD(增,查,改,删)。

所以,可以这么说modelSchema的包装器,通过包装实现了Schema结构的数据与MongoDB数据库之间的交互。

注:在开发过程中,使用的都是ModelSchema的实例,所以可以理解文章开篇说的对象转换对象数据模型。具体可参考下面的示例代码。

引用mongoose

使用前需要先安装mongooe,可通过yarn install mongoose来安装,然后通过如下代码来引用:

// 引用mongoose
let mongoose = require('mongoose')

说明:SchemaModel不是显式的连接到了数据库,为什么这么说呢,因为开发的过程中,不是使用的mongoose.connect("mongodb://127.0.0.1:27017")返回的对象创建的SchemaModel,而是直接使用的mongoose的引用,这样做的好处很明显,极大地提升了性能。

mongoose定义使用了单例设计模式,所以使用require返回了一个单例对象,这在开发中比较常见,对于写自己的库有指导意义。

连接到MongoDB数据库

// 引用mongoose
let mongoose = require('mongoose')
// 连接到demo测试数据库
mongoose.connect('mongodb://127.0.0.1:27017/demo')

定义一个Schema

每一个collection中的所有document都使用同一个Schema定义的field。每一个document对象的键名通过Schema来定义。

// 引用mongoose
let mongoose = require('mongoose')
// 连接到demo测试数据库
mongoose.connect('mongodb://127.0.0.1:27017/demo')
// 定义并实例化一个Schema
let userSchema = new mongoose.Schema({
  firstname: String,
  lastname: String
})

同样在Schema中可以对field进行验证,如:firstnameString类型的。

Schema的字段值可以是Array,String,Boolean,Buffer,Date,Number,ObjectId,或者Mixed(泛型,或者一个可变化的数据类型)。

定义并实例化一个model

// 引用mongoose
let mongoose = require('mongoose')
// 连接到demo测试数据库
mongoose.connect('mongodb://127.0.0.1:27017/demo')
// 定义并实例化一个Schema
let UserSchema = new mongoose.Schema({
  firstname: String,
  lastname: String
})
// 定义一个Model
let UserModel = mongoose.model('User', userSchema)
// 实例化一个Model
let person = new Usermodel({
  firstname: '东坡',
  lastname: '苏'
})

可能有的人会比较疑惑,为什么Schema的定义和实例化可以放在一起,而Model的定义和实例化要分开?因为schema的实例不牵涉到具体的操作,而Model的实例往往牵涉到复杂的操作。所以前者在开发中往往两个步骤一起来做,后者分开来做。

mongoose的CRUD

添加数据

person
  .save()
  .then(doc => {
    console.log(doc)
  })
  .catch(err => {
    console.error(err)
  })

查看数据

UserModel
  .find({
    lastname: '苏'   // query
  })
  .then(doc => {
    console.log(doc)
  })
  .catch(err => {
    console.error(err)
  })

更新数据

UserModel
  .findOneAndUpdate(
    {
      lasttname: '苏'  // query
    }, 
    {
      firstname: 'xxx'   // field:values 的更新
    },
    {
      new: true,                       // 返回更新后的document
      runValidators: true              // 在更新前进行验证
    })
  .then(doc => {
    console.log(doc)
  })
  .catch(err => {
    console.error(err)
  })

删除数据

UserModel
  .findOneAndRemove({
    firstname: '东坡'
  })
  .then(response => {
    console.log(response)
  })
  .catch(err => {
    console.error(err)
  })

当然,mongoose还提供了很多很实用的api,这里就不多说了。mongoose queries

mongoose系列文章

阅读 2.8k

前端周分享
我需要一个苹果,一个可以与你交换的苹果

心态很重要,我始终相信没有不会做的,只有不想做的,在这个人人都聪明的今天,你不凭智慧,只需努力就...

3.5k 声望
0 粉丝
0 条评论
推荐阅读
webpack引入第三方库的方式,以及注意事项
然后,在使用jquery的模块文件中,通过import $ from 'jquery'或者var $ = require('jquery')来引入。

缘自世界6阅读 5.5k

前端性能优化(图文并茂,通俗易懂)
默认情况下,我们静态导入的所有模块都会添加到初始捆绑包中。使用默认 ES2015 导入语法 导入的模块将静态导入。import module from 'module'

寒水寺一禅26阅读 2.8k评论 1

「彻底弄懂」this全面解析
当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在 哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this就是记录的其中一个属性,会在 函数执行的过程中用到...

wuwhs11阅读 1.3k

封面图
图解JS中的事件循环
1、js单线程,并非指js只有一个线程,而是同一时刻只能有一个线程在工作。2、js中,主线程之外,还有其他线程,比如事件循环线程,定时器触发线程,http异步线程, 浏览器事件线程。3、在js主线程中,分为两个子...

寒水寺一禅6阅读 2.2k

为什么vue.config.js中使用require,而vite.config.js使用 import?
偶然一次发现,他们两个的引入模块的方式不一样,在好奇心的驱使下,便开始一探究竟。1、vue.config方式打开项目的package.json,找到 scripts位置。找到 vue-cli-service 命令,通常命令都位于当前项目的node_mo...

寒水寺一禅9阅读 1.7k

「🌟技术探索🌟」借助 CI / CD 实现前端应用的快速回滚
在 上一轮优化 里, 我们通过优化一些构建工具和流程, 把构建耗时优化到了 4min 左右,整体发布耗时从 15min 优化到了 8 min 左右, 有较大提升, 但是依旧存在提升空间。

皮小蛋3阅读 2.8k评论 2

Taro源码-项目build一个weapp的过程
基于Taro3.5.5此前,我们学习了cli创建一个Taro项目,并在packages/taro-cli/bin文件夹下创建了简单的Taro项目appname,接着看一下用Taro项目去build一个微信小程序weapp的过程

perkz4阅读 1k评论 2

封面图

心态很重要,我始终相信没有不会做的,只有不想做的,在这个人人都聪明的今天,你不凭智慧,只需努力就...

3.5k 声望
8.4k 粉丝
宣传栏