【SECTION 11】数据建模思路,Mongoose使用

1,404 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

MongoDB 数据库介绍

基本概念

image.png

  • 数据库database:多个集合构成一个数据库。一般一个项目使用一个数据库
  • 集合collection:多个文档构成一个集合(后文的people、notes)
  • 文档document:类似于JSON对象Object(后文的person,一条用户的信息)
  • 字段filed:类似于JSON对象的各个键Key(后文的name、number) image.png

优势

image.png

基于JavaScript,完全通过操作JSON对象实现增查删改,数据本身也以JSON格式储存,与 Node.js + Express技术栈相通;数据库本身并不关心存储在数据库中的数据的结构,可以在同一集合中存储具有完全不同字段的文档,可以随时扩充等。

与关系型数据库对比

BSON与JSON不同的地方,value是有类型的(typed) image.png

工程应用

数据建模的方法很重要,一定要理解这几张图,选择适合的模型和引用关系,对梳理逻辑,数据库查询储存性能优有重要意义。

对数据建模

image.png

1对1,1对多,多对多

image.png

引用 vs 嵌入

image.png image.png

子引用,父引用,双向引用

image.png

建模总结

根据数据查询和更新的方法设计数据模型。

image.png

使用数据库

MongoDB Atlas

不用本地安装。

MongoDB Atlas创建并登录到你的账户,Atlas 会建议你创建一个数据库,接着用

  • database access选项卡为数据库创建用户凭据,可以让你的应用连接到数据库
  • Network access定义允许访问数据库的 IP 地址。方便起见设为0.0.0.0/0,表示 Anywhere

Mongoose

Mongoose 可以被描述为 object document mapper (ODM) ,它将 JavaScript 对象保存为 Mongo 文档。 image.png

连接

  • 选择Connect image.png
  • 选择Connect your application: image.png 该视图显示MongoDB URI,这是将提供给我们将添加到应用的 MongoDB 客户端库的数据库地址。

连接:

mongoose
  .connect(url)
  .then((result) => {
    console.log('connected to MongoDB');
  })
  .catch((error) => {
    console.log('error connecting to MongoDB:', error.message);
  });

命令行输入: node mongo.js password Anna 040-1234556

访问命令行参数const password = process.argv[2]

基本使用

定义Schema和匹配的model

该模式定义了存储在任何给定集合中的文档的形式。

  • 模式告诉 Mongoose 如何将 note 对象存储在数据库中。
  • 模型是一个构造函数,它连接了模式与集合,负责实际对数据库进行读写。
const personSchema = new mongoose.Schema({
    name: String,
    number: String
})
const Person = mongoose.model('Person', personSchema)

tips: 在模型定义中,第一个 Person 参数是模型的单数名,Mongoose 根据这个模型名自动将相关集合命名为小写复数 people ,再举例子:Note——notes

验证数据格式

在数据存储到数据库之前验证数据格式,在定义模式时限制:

const personSchema = new mongoose.Schema({
  name: {    
      type: String,    
      minLength: 3,   
      required: true  
  },  
  number: {     
      type: String,   
      required: true  
  },  
})

创建和保存对象

创建:即创造构造函数的实例,此处硬编码示例,实际中可以配合命令行参数创建

const person = new Person({
    name: "Ava Meth" ,
    number: "029-887543"
})

保存:可以通过 save 方法实现的,当对象保存到数据库时,调用then方法提供给该对象的事件处理。

  person.save().then(result => {
    console.log(
      `added ${process.argv[3]} number ${process.argv[4]} to phonebook`
    );
    mongoose.connection.close();
  });

image.png

在数据库中查看保存情况: image.png

从数据库中获取对象

不限制搜索,得到所有数据:

  Person.find({}).then(result => {
    result.forEach(p => {
      console.log(p);
    });
    mongoose.connection.close();
  });
  console.log('get all people');

image.png

限制搜索

  Person.find({ number: '029-887543' }).then(result => {
    console.log(result);
    mongoose.connection.close();
  });

以数组形式返回: image.png

格式化Mongoose返回的对象

  • Mongoose 对象的 id 属性是一个对象,安全起见,我们将其转换为字符串
  • 一般我们也不将 mongo 版本控制__v字段返回到前端 修改Schema 的 toJSON 方法:
personSchema.set('toJSON', {
  transform: (document, returnedObject) => {
    returnedObject.id = returnedObject._id.toString()
    delete returnedObject._id
    delete returnedObject.__v
  }
})

参考资料

MongoDB中文手册

Mongoosejs.com