【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (七):MongoDB的设置

本项目旨在学习如何快速使用 nodejs 开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师)
由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序(并非循序渐进的教学文档)。建议配合项目源码node-mongodb-template 。

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (一):项目简介及安装依赖

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (二):项目文件夹架构及路由的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (三):Cors的设置及.env文件的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (四):状态码的使用

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (五):POST上传文件的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (六):token的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (七):MongoDB的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (八):API说明(暂时完结,后续考虑将在线版mongoDB变为本地版)

MongoDB的设置

选择了MongoDB的在线版数据库,可以申请免费的空间使用,点击网址申请。申请和创建库之后,复制针对nodejs提供的code,如下

mongodb+srv://db:<db_password>@test.gx6wc.mongodb.net/?retryWrites=true&w=majority&appName=test

将其中<db_password>替换成你设置的密码。

接下来就可以在nodejs中使用该云数据库了。

连接数据库

  • 安装依赖

pnpm i --save mongoose

  • 引用依赖
//app.js
const mongoose = require('mongoose');
  • 连接数据库
mongoose.connect('mongodb+srv://db:'
+process.env.MONGO_ATLAS_PW
+'@test.gx6wc.mongodb.net/?retryWrites=true&w=majority&appName=test');mongoose.Promise = global.Promise;

mongoose API学习

Model数据结构声明
Type数据类型
  • mongoose.Schema.Types.ObjectId 自动生成的id;
  • Number 数字型;
  • String 字符串型;
required:是否必要
default:默认值
ref:关联的表/数据结构/model
unique:是否唯一
match:数据正则检查匹配
定义数据结构

mongoose.Schema({...})

mongoose.model('<modelName>', <ModelSchema>)

//product.js
const mongoose = require('mongoose');const productSchema = mongoose.Schema({_id:mongoose.Schema.Types.ObjectId,name:{type:String, required:true},price:{type:Number, required:true},productImage:{type:String, required:true},
})module.exports = mongoose.model('Product', productSchema);
//order.js
const mongoose = require('mongoose');const orderSchema = mongoose.Schema({_id:mongoose.Schema.Types.ObjectId,//product的值为ObjectId,与【Product】关联product:{type:mongoose.Schema.Types.ObjectId, required:true,ref:'Product'},quantity:{type:Number, default:1},
})module.exports = mongoose.model('Order', orderSchema);
//user.js
const mongoose = require('mongoose');const userSchema = mongoose.Schema({_id:mongoose.Schema.Types.ObjectId,email:{type:String, required:true,unique:true,//校验email的格式match:/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/},password:{type:String, required:true},
})module.exports = mongoose.model('User', userSchema);
数据操作
类型引用
//product Model定义的位置
const Product = require('../models/product');
exec: 执行

执行mongoose的query操作后,调用exec()方法;

Product.find().then();
Product.find().exec().then();

区别在于: mongoose 的所有查询操作返回的结果都是 query (官方文档是这样写的),并非一个完整的promise。
而加上.exec()则将会返回成为一个完整的 promise 对象,但是其是 mongoose 自行封装的 promise ,与 ES6 标准的 promise 是有所出入的(你应该会在控制台看到相关的警告),而且官方也明确指出,在未来的版本将会废除自行封装的promise,改为 ES6 标准,因此建议楼主在使用过程中替换为 ES6 的 promise,如下:

const mongoose = require(‘mongoose’);
mongoose.Promise = global.Promise;

find: 查询
//查询全部
Product.find();
Product.find().exec().then(docs=>{//docs是products数组
});//查找所有满足条件的数据
//条件格式 {prop:value,...}
User.find({email: req.body.email}).exec().then(docs=>{//docs是数组
})//查询满足条件的数据中的第一个
Product.findOne();
User.findOne({email: req.body.email}).exec().then(doc=>{//doc是一个对象
})//查询指定Id的数据(id唯一)
Product.findById();
Product.findById(id).exec().then(doc=>{//doc是一个对象
})Product.findOneAndDelete();
Product.findOneAndReplace();
Product.findOneAndUpdate()
where: 查询条件
Product.where({email: req.body.email}).fineOne().exec().then(doc=>{});
select: 指定属性
//Product包含属性:name, price, _id//需求是只显示name和price
Product.find().select('name price').exec().then(docs=>{//docs是products数组
});
populate: 子表属性
//Order包含属性:product quantity _id
//product是子表数据的_id//需求是显示product的详细属性
Order.find().select('product quantity').populate('product','name price').exec().then(docs=>{});
//{
//  product:{
//    name:"",
//    price:11
//  },
//  quantity:1,
//}
save: 新增
const product = new Product({_id:new mongoose.Types.ObjectId(),name:req.body.name,price:req.body.price,productImage:req.file.path});
product.save().then(result=>{//result和product实例相同})
updateOne: 修改
const updateOpts = {name:"",price:22,
};
//找到指定id的数据,并修改对应字段
Product.updateOne({_id:id},{$set:updateOpts}).exec().then(result=>{      
})
deleteOne: 删除
Product.deleteOne({_id:id}).exec().then(result=>{     
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/56762.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android View的事件分发机制

前言 本文由于介绍本人关于View的事件分发机制的学习&#xff0c;如有不恰当的描述欢迎指出。 View基础 什么是View ​ View是Android中所有控件的基类&#xff0c;不管是Button、TextView、LinearLayout&#xff0c;它们的共同基类都是View。也就是说&#xff0c;View是界…

K8S配置storage-class

简介 Kubernetes支持NFS存储&#xff0c;需要安装nfs-subdir-external-provisioner&#xff0c;它是一个存储资源自动调配器&#xff0c;它可将现有的NFS服务器通过持久卷声明来支持Kubernetes持久卷的动态分配。该组件是对Kubernetes NFS-Client Provisioner的扩展&#xff0…

腾讯云跨AZ部署FortigateHA备忘录

随时保存配置 config system globalset admintimeout 480set alias "FortiGate-VM64-KVM"set gui-auto-upgrade-setup-warning disableset hostname "FG-Slave"set revision-backup-on-logout enableset revision-image-auto-backup enableset timezone &…

179.最大数

目录 题目解法sort可以自定义排序规则 题目 给定一组非负整数 nums&#xff0c;重新排列每个数的顺序&#xff08;每个数不可拆分&#xff09;使之组成一个最大的整数。 注意&#xff1a;输出结果可能非常大&#xff0c;所以你需要返回一个字符串而不是整数。 解法 class S…

Android开发兼容性问题3万字保姆级教程(Android版本、屏幕、多语言、硬件、第三方库、权限)

目录 第一章 Android版本兼容性 1.1 版本众多的挑战 1.2 设置版本参数 1.3 API版本检测 1.4 兼容性实例 使用minSdkVersion和targetSdkVersion 1.5 版本更新的应对策略 第二章 屏幕尺寸与分辨率兼容性 2.1 屏幕尺寸的多样性 2.2 响应式布局 2.3 drawable资源管理 使…

面向对象与设计模式第一节:深入理解OOP

第三章&#xff1a;面向对象与设计模式 第一节&#xff1a;深入理解OOP 面向对象编程&#xff08;OOP&#xff09;是一种编程范式&#xff0c;它将程序结构视为由对象组成&#xff0c;促进了代码的重用性和可维护性。在这一课中&#xff0c;我们将深入分析OOP的四个基本特性&…

Flutter鸿蒙next 布局架构原理详解

✅近期推荐&#xff1a;求职神器 https://bbs.csdn.net/topics/619384540 &#x1f525;欢迎大家订阅系列专栏&#xff1a;flutter_鸿蒙next &#x1f4ac;淼学派语录&#xff1a;只有不断的否认自己和肯定自己&#xff0c;才能走出弯曲不平的泥泞路&#xff0c;因为平坦的大路…

【mysql】转义字符反斜杠,正则表达式

1.mysql插入 1.1插入-反斜杠规则&#xff1a; ​ 在MySQL中&#xff0c;反斜杠在字符串中是属于转义字符&#xff0c;经过语法解析器解析时会进行一次转义&#xff0c;所以当我们insert反斜杠&#xff08;\&#xff09;字符时&#xff0c;如 insert “\” 在数据库中最…

[JAVAEE] 多线程的案例(三) - 线程池

目录 一. 什么是线程池 二. 线程池的作用 三. java提供的线程池类 四. ThreadPoolExecutor的构造方法及参数理解 1. int corePoolSize: 核心线程数. 2. int maximumPoolSize: 最大线程数 核心线程数 非核心线程数 3. int keepAliveTime:非核心线程允许空闲的最大时间. …

DataX简介及使用

目录 一、DataX离线同步工具DataX3.0介绍 1.1、 DataX 3.0概览 1.2、特征 1.3、DataX3.0框架设计 1.4、支持的数据元 1.5、DataX3.0核心架构 1.6、DataX 3.0六大核心优势 1.6.1、可靠的数据质量监控 1.6.2、丰富的数据转换功能 1.6.3、精准的速度控制 1.6.4、强劲的…

第五十四章 安全元素的详细信息 - DerivedKeyToken 详情

文章目录 第五十四章 安全元素的详细信息 - <DerivedKeyToken> 详情详情消息中的位置 第五十四章 安全元素的详细信息 - 详情 <DerivedKeyToken> 的目的是携带发送者和接收者可以独立使用的信息来生成相同的对称密钥。这些方可以使用该对称密钥对 SOAP 消息的相关…

正则表达式和通配符

文章目录 正则表达式和通配符的区别正则表达式&#xff08;Regex&#xff09;通配符&#xff08;Wildcards&#xff09;总结 正则表达式的概念正则表达式的由来为什么要使用正则表达式 正则表达式的语法组成修饰符元字符\f\b\B 在Linux中的基础正则和扩展正则基础正则(BRE)^$.*…

人脸应用实例:性别年龄预测

在当今科技飞速发展的时代&#xff0c;人脸识别技术已经从科幻电影走进了我们的日常生活。通过算法来识别人脸的特征&#xff0c;进而判断身份、年龄和性别&#xff0c;这一技术正逐步改变着我们的生活方式。今天&#xff0c;我们就来探讨一下基于深度学习的人脸应用实例——性…

面试时被问到“Scaling Law”,该怎么答?

在大模型的研发中&#xff0c;通常会有下面一些需求&#xff1a; 计划训练一个 10B 的模型&#xff0c;想知道至少需要多大的数据&#xff1f; 收集到了 1T 的数据&#xff0c;想知道能训练一个多大的模型&#xff1f; 老板准备 1 个月后开发布会&#xff0c;给的资源是 100 …

vue父子传参的方式——Prop

Prop 每一个组件都有一个props的属性&#xff0c;用来接收外部传递的数据 这里我拿一个分页组件为例&#xff1a; 一、基础语法 1、父组件传递数据 父组件在向子组件传递数据时&#xff0c;基础语法如下&#xff1a; <template><div><common-page :pagina…

Linux安装Nginx教程(rpm安装方式)

本章教程,主要介绍如何在Linux Centos7系统上,使用rpm的方式进行安装Nginx。 一、安装wget插件 如果不存在wget下载插件,需要安装一下。 yum install -y wget二 、下载rpm安装包 官方提供的rpm下载地址:https://nginx.org/packages/centos/7/x86_64/RPMS/ <

【Nginx系列】499错误

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Java面试题——计网篇2

1.get和post请求的区别 用途不同&#xff1a; GET请求用于从服务器获取数据&#xff0c;它不会改变服务器上的数据。POST请求用于向服务器提交数据&#xff0c;通常用于修改服务器上的数据。 数据传输方式不同&#xff1a; GET请求将数据附加在URL后面&#xff0c;通过问号(?)…

Postman常见问题及解决方(全)

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、网络连接问题 如果Postman无法发送请求或接收响应&#xff0c;可以尝试以下操作&#xff1a; 检查网络连接是否正常&#xff0c;包括检查网络设置、代理设置…

软考中级嵌入式系统设计师笔记分享(二)

1.TTL 电路是电流控制器件&#xff0c;而CMOS 电路是电压控制器件。 2.TTL 电路的速度快&#xff0c;传输延迟时间短(5-10ns)&#xff0c;但是功耗大。 常见的串行总线有 SPI、II2C、USB、RS232/RS422/RS485、CAN等;高速串行总线主要有 SATA、PCIE、IEEE 1394、Rapidl0、USB 3…