Mongoose 以及 基本 CRUD

Mongoose 介绍

Mongoose 是 MongoDB 的一个抽象层,有点像是 Express 对 Node 的感觉。

官方文档的两个介绍大概说明了 Mongoose 是干嘛的:

Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment. Mongoose supports both promises and callbacks.

Let’s face it, writing MongoDB validation, casting and business logic boilerplate is a drag. That’s why we wrote Mongoose.

首先,Mongoose 是一个在异步环境下使用的 MongoDB 对象模型工具,其次,Mongoose 可以减少 MongoDB 验证、类型转换,以及业务逻辑样板的代码量。

关于 MongoDB 的部分,可以看这个——MongoDB 的安装和基础 CRUD,这里要用的也不会超过之前对 MongoDB 的了解了。

安装 Mongoose

Mongoose 在 npm 上有依赖,可以直接用 npm 安装:

npm i mongoose

等下载好了就可以直接在项目里面使用 Mongoose 了。

连接数据库

  • 配置 config.env

    config.env 中的配置如下:

    # 远程的MongoDB路径,我用的是 Atlas 的免费版进行学习,这点在上面的 MongoDB 文章里提到,感兴趣的可以去看看
    DATABASE=mongodb+srv://<USERNAME>:<PASSWORD>@<CLUSTER_ENV>/<DOCUMENTS>?retryWrites=true&w=majority
    # 上面用 <> 包起来的变量都会被代替掉,不会放出来的
    DB_USERNAME=some-random-username
    DB_PASSWORD=some-random-password
    CLUSTER_ENV=atlas-cluster-env
    DOCUMENTS=atlas-documents# 也可以使用本地的 Mongodb 进行学习
    # 这里的 <DOCUMENTS> 用自己想用的就行了,如果没有的话,MongoDB 会自己创立的
    DATABASE_LOCAL=mongodb://localhost:27017/<DOCUMENTS>
    
  • 连接数据库

    目前在 server.js 文件中进行连接

    // 导入必要的包
    const mongoose = require("mongoose");
    const dotenv = require("dotenv");// dotenv 必须先读取环境配置,等 app 声明调用了再找配置就来不及了
    dotenv.config("./config.env");// 必要的环境配置
    const app = require("./app");
    // replace 必要的 connection string
    // 包括 用户名、密码、cluster、document,确保和云端信息一致
    const DB = process.env.DATABASE.replace("<USERNAME>",process.env.DB_USERNAME
    );// 连接 MongoDB
    // 云端的连接方法
    mongoose.connect(DB, {// 一些优化和减少 warning 的配置useNewUrlParser: true,useCreateIndex: true,useFindAndModify: false,useUnifiedTopology: true,}).then(() => {console.log("DB successfully connected");});
    // 本地的连接方法基本差不多,只是需要把 DB 换成 process.env.DATABASE_LOCAL 就好了
    /*
    mongoose.connect(process.env.DATABASE_LOCAL, {// 一些优化和减少 warning 的配置useNewUrlParser: true,useCreateIndex: true,useFindAndModify: false,useUnifiedTopology: true,}).then(() => {console.log("DB successfully connected");});*/
    

这个时候在本地运行的 express 服务器就可以连接上远程的数据库了。

创建 Model

这是 Model 层的业务,先创建一个 schema,然后再以 model 的形式导出,让 controllers 使用。

const mongoose = require("mongoose");// 为了方便,暂时还不会自创 Schema,里面的 type 都是 JS 自己的
const productSchema = new mongoose.Schema({product: {type: String,// 第二个参数会决定 报错信息required: [true, "This will be a warning message"],// 目前假设每个产品都有独一无二的名字unique: true,trim: true,},createdAt: {// MongoDB 会依照 传过去的毫秒 自动创建当前时间type: Date,default: Date.now(),},price: {type: Number,required: [true, "A product must have price"],},
});const Product = mongoose.model("Product", productSchema);module.exports = Product;

实现 Controller

即实际的业务逻辑,这里假设 routers 里面已经通过 request 调用了 controller 里面的函数。最外层的文件如下:

// 即上文 export 的 Product
const Product = require('../models/productModel');// 等待实现的 CRUD
exports getAllProducts = async (req, res) => {}exports getProduct = async (req, res) => {}exports createProduct = async (req, res) => {}exports deleteProduct = async (req, res) => {}exports updateProduct = async (req, res) => {}

Create

createProduct 方法。

exports.createProduct = async (req, res) => {// 从 req.body 里面已经穿来了一个 JSON对象// 现在暂时是在 postman 里面写死的,之后会写 View 或者用 React 再做一个 VMtry {const product = await Product.create(req.body);res.status(201).json({status: "Success",data: {product,},});} catch (err) {res.status(400).json({status: "fail",message: err,});}
};

Read

即两个方法:find()findById()

exports.getAllProducts = async (req, res) => {try {const products = await Product.find();res.status(200).json({status: "Success",results: products.length,data: {products,},});} catch (err) {res.status(404).json({status: "fail",message: err,});}
};exports.getProduct = async (req, res) => {try {const product = await Product.findById(req.params.id);res.status(200).json({status: "Success",data: {product,},});} catch (err) {res.status(404).json({status: "fail",message: err,});}
};

Update

还没有实现 updateMany(),先实现 findByIdAndUpdate(),这个部分的代码是被 patch() 所调用的。

exports.updateProduct = async (req, res) => {try {const product = await Product.findByIdAndUpdate(req.params.id, req.body, {// new 是为了返回更新后的 数据,默认返回是未被更新的数据new: true,runValidators: true,});res.status(200).json({status: "Success",data: {product,},});} catch (err) {res.status(404).json({status: "fail",message: err,});}
};

Delete

findByIdAndDelete() 函数。

exports.deleteProduct = async (req, res) => {try {await findByIdAndDelete(req.params.id);} catch (err) {res.status(204).json({status: "Success",});res.status(404).json({status: "fail",message: err,});}
};

到这里基础的 CRUD 就全都完成了。

试了之后才发现,真的非常简单。

下一步做的优化就是 findById() 里面传 query param,一些过滤的优化,然后再考虑把 CRUD 的 try{} catch (err) {} 封装一下。

目前的 try/catch 其实也非常简陋,很多判断都没有做。

学习项目的配置

简单地说一下吧,之前好像在那个学习笔记里面有放过……不过现在结构这么简单,有时间找都重新写完了。

之后还是应该抽空把 node 和 express 部分的笔记单独抽离出来。

结构

一个典型的 MVC 结构,如下:

|- src
|   |- controllers
|   |   |- productController.js
|   |- models
|   |   |- productModel.js
|   |- routes
|   |- app.js
|   |- config.env
|   |- package.json
|   |- server.js

目前 View 还没有开始折腾,现在折腾 API 部分,这也就是为什么开始学 MongoDB 和用 Mongoose 了。

  • mondels
    里面放的就是 MVC 里的 M,即 Model。这里面主要是一些 Schema Definition,定义数据类型、是否是必须的,等一些细节方面的东西。在 Schema 里面定义好了之后,如果在进行 CRUD 的操作时,数据不对的话,就会报错。

    所以说在 Mongoose 的介绍里面也说了,写 MongoDB 的验证很烦,主创开发 Mongoose 的原因之一就是为了操作 MongoDB 的时候没这么麻烦。

  • controllers

    处理的是业务逻辑,即传统的 CRUD 操作。

  • routes

    处理的是路由,在 RESTful API 里面,资源的路径名字始终保持一致,根据传来的 HTTP request 去进行 CRUD 的操作。这时候就需要路由去判断传来的 HTTP request,随机调用对应的 controller 里对应的方法。

    具体可以查看 IBM 的文档,在 参考 里。

  • app.js

    app 相关的配置,目前负责调用配置一些简单的中间件,以及对 routers 的管理。

  • config.env

    一些配置,包括 MongoDB 网址、用户名、密码之类的会放在这里方便管理。

  • package.json

  • server.js

    服务器相关的,目前连接 MongoDB 的操作会放在这里。

package.json

在这篇教学里面,除了 Mongoose 之外,还会用到 dotenv 去进行环境配置。

"dependencies": {"dotenv": "^8.2.0","mongoose": "^5.12.3"
}

参考

-IBM - REST APIs

Mongoose 以及 基本 CRUD相关推荐

  1. 给mongoose find()/findOne()查询的结果添加额外的属性

    在学习 mongoose 的时候,碰到一个需要注意的地方. 给查询结果添加额外的属性时,不能直接在这个结果对象上添加属性.原因和解决方案往下看. 假设 User 集合有一个 name 字段: cons ...

  2. Node+express+mongoose前端实现简单crud接口

    Node+express+mongoose前端实现建单crud接口 准备工作:需要安装依赖如下:node,express,mongoose,cors,requier-all 入口文件:index.js ...

  3. Mongoose的CRUD方法

    mongoose 的CRUD -C creat: 模型对象.create(文档对象,回调函数) 模型对象.create(文档对象) -R Read: 模型对象.find(查询条件,[投影]) 注意⚠️ ...

  4. [转] mongoose学习笔记(超详细)

    名词解释 Schema: 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 Model: 由Schema编译而成的假想(fancy)构造器,具有抽象属性和行为.Model的每一个实例(ins ...

  5. Nodejs+Express学习二(Mongoose基础了解)

    学习Node注定少不了与数据库打交道,而MongoDB和Node可以说是绝配,这篇主要是简单介绍Mongoose这个模块. 由于本人也是边学边写的这篇文章,绝对会有新手的味道,请大神看到这里就表往下看 ...

  6. 前端笔记之NodeJS(四)MongoDB数据库Mongoose自制接口MVC架构思想|实战

    一.MongoDB数据库 1.1 NoSQL简介 随着互联网web2.0网站的兴起,传统的SQL数据库(关系数据库)在应付web2.0网站,特别是超大规模和高并发的SNS(social network ...

  7. 手把手教你用nestjs框架7分钟生成crud风格接口

    Tobenew  ,感谢! node.js mongodbnestjs 1.安装nest.js框架 nest.js官方开发文档 全局安装nest框架 npm i -g @nestjs/cli 2. 新 ...

  8. nodejs mongoose建模实践

    2019独角兽企业重金招聘Python工程师标准>>> 一直以来mongoose学习都是比较麻烦的,mongoose-cli试图简化学习和测试mongoose部分,并通过app开发流 ...

  9. mongoose mysql_mongoose入门

    mongoose入门 MongoDB是一个开源的NoSQL数据库,相比MySQL那样的关系型数据库,它更显得轻巧.灵活,非常适合在数据规模很大.事务性不强的场合下使用.同时它也是一个对象数据库,没有表 ...

最新文章

  1. Linux下安装 boost 库
  2. C语言程序设计 细节总结(第9章 结构体共用体枚举)
  3. 统计数字,空白符,制表符_为什么您应该在HTML中使用制表符空间而不是多个非空白空间(nbsp)...
  4. 每日一皮:从项目的开始到结束,开发人员的变化...
  5. [发布]Lucene索引分析工具Luke.Net 0.5升级版 (兼容Lucene.Net 2.9.4.1)
  6. spring源码分析之spring-jms模块详解
  7. HP DL388G5 安装64位linux虚拟系统出错!
  8. android 8种对话框(Dialog)使用方法汇总
  9. 40访问者模式(Visitor Pattern)
  10. LintCode 1671. 玩游戏(贪心、难)
  11. 【2019杭电多校第六场1008=HDU6641】TDL(思维)
  12. 一文带你快速全面掌握Java反射机制面试题
  13. Meterpreter命令详解
  14. 5G NR — 基站(Base Station)
  15. python基础螺旋线
  16. 信息安全从业者书单推荐
  17. IROS2020 论文阅读
  18. 为什么OSPF在广播网络里面,DD和LSR采用单播,而LSU hello采用组播。
  19. 2023-2029全球斑马鱼行业调研及趋势分析报告
  20. pc_lint的用法转

热门文章

  1. 程序员日常:男程序员手腕上一般戴什么?程序员的第一只手表
  2. 海外主体企业微信公众号如何开通及认证?
  3. i.MX 6ULL 驱动开发 十四:LED(paltform驱动框架)
  4. 【Skywalking】集成Sl4fj2报错:NoClassDefFoundError,com/lmax/disruptor/TimeoutBlockingWaitStrategy
  5. vue中将 后台返回的0,1等 代码转换成 男,女等汉字。
  6. Android仿酷狗动感歌词(支持翻译和音译歌词)显示效果
  7. C语言应该怎么玩——函数
  8. poi操作ppt生成图表
  9. MongoDB 自学笔记(入门级教程)
  10. Code First 2