这是我参与更文挑战的第2天,活动详情查看: 更文挑战”
原文链接
express的使用(五) 简单的使用mongodb 不要脸的求关注,希望能让大家批评我的不足点,一键三连最好了
看前提示
本篇主要描述关于express中使用mongodb以及mongodb的简单介绍还有初步使用,不涉及任何常用的语法,不建议有mongodb跟项目经验开发的人看。
名词介绍
NoSQL
对于nosql,相比是大家第一次接触mongodb的时候都被宣传的一个概念,先黏贴一段介绍吧
NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
从新手理解的角度来说,即传统的表格被剔除了,取而代之的是一个又一个的BSon数据,且格式不做要求,如:一开始的格式为{id:1,phone:1},后续开发,表格添加了ip字段,而我们不需要在表上添加ip字段,只需要直接修改数据的内容为{id:1,ip:2}即可
database collection document field
这四者为了让大家有个直观的感觉,就直接贴上一张图来说明,包含关系,
database>collection>document>field
ObjectId
ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时,接下来的 3 个字节是机器标识码,紧接的两个字节由进程 id 组成 PID,最后三个字节是随机数
objectId对我们来说是一个唯一标识,更多时候只是用来解析,看看这条数据的生成时间
MongoDB Compass
一个可以直观查看到我们db中数据的工具,毕竟几千万条数据的时候,用terminal打印出来还是很离谱的。
下载并安装mongodb
在菜鸟教程上有不错的安装教程,我就直接粘贴过来,我不希望做太多没用的重复工作,毕竟人家有了直观的教程
mongodb 6.x后的版本需要另外安装shell,才可以启动mongodb的服务
启动并连接mongodb
在上一步下载shell还有mongodb之后,记得分别切换到bin的目录下。再打开两个终端。
启动mongodb的服务
net start MongoDB
关闭mongdb的服务
net stop MongoDB
连接本地的mongodb服务
.\mongosh mongodb:localhost
请注意,由于没有配置环境变量的path,所以需要在运行命令时候使用./的方式
使用shell操作mongodb
本意是直接使用代码来操作db,但是我还是希望大家有个直观的概念,所以在这儿不合时宜的介绍下mongodb的一些shell操作,以便加深大家的理解还有记忆能力**
**
查看当前mongodb的信息
show dbs
切换库
如果库存在,会直接切换过去,如果不存在会直接创建并且切换过去
use td_hero_shell
创建collection
db.createCollection("hero")
增加数据
db.hero.insertOne({ time:"2023-05-26", timestampt:"1685062800000", hero_name:"爆破鬼才", from:"新玩家七天奖励", from_index:1})
修改数据
db.hero.updateOne({ hero_name: "爆破鬼才"}, { $set: { "hero_name": "爆破大师" } })
删除数据
db.hero.deleteOne({ _id: ObjectId("648c94102db900a4b21705aa")})
批量输入数据
db.hero.insertMany([ { time: "2023-05-26", timestampt: "1685062800000", hero_name: "爆破大师", from: "新玩家七天奖励", from_index: 1 }, { time: "2023-05-30", timestampt: "1685062800000", hero_name: "炎魔", from: "勇气宝箱", from_index: 2 }])
查看数据
db.hero.find()
mongodb compass查看数据
2023-06-17 12:37,在笔者编辑文章的时候,1.3.7版本会有报错,因此降低了版本为1.2.5
https://www.filehorse.com/download-mongodb-compass/58166/download/
使用代码操作mongodb
依赖版本
"mongoose": "^7.3.0"
mongoose文档链接
https://mongoosejs.com/
接入mongoose
首先,写代码之前,我们可以看下mongoose中的"快速开始",最简洁的代码如下,实现的功能也是很简单,就是将mongoose接入到我们的项目中,并且让我们连接到db去
const mongoose = require('mongoose');main().catch(err => console.log(err));async function main() { await mongoose.connect('mongodb://127.0.0.1:27017/test'); // use `await mongoose.connect('mongodb://user:password@127.0.0.1:27017/test');` if your database has auth enabled}
而我们考虑下我们代码的实际情况,可以将db连接部分的js文件写在一个专属的文件中,然后再server.js中去引入并使用它,主打的就是一个分工合作。方便抽离
const mongoose = require('mongoose');// 链接到mongodb// 获取链接的实体对象const connect = mongoose.connection// 连接的error处理connect.on("error", () => { console.log("mongodb链接错误============>");})// 只监听一次的连接打开connect.once('open', () => { console.log("mongodb连接打开了========>")})mongoose.dbConnect = () => { mongoose.connect('mongodb://localhost/td_hero_shell');}module.exports = mongoose;
const mongodb=require("./src/db");const express = require("express");const app = express();const path = require("path");const { blogRouter } = require("./src/router/blog");const { userRouter } = require("./src/router/user");app.listen(3000, () => { console.log("服务已启动");});//mongodb.dbConnect();app.set("views", path.join(__dirname, "views"));app.set("view engine", "pug");//cookie模块const cookieParser = require("cookie-parser");app.use(cookieParser());app.use("/blog", blogRouter);app.use("/user", userRouter);
运行之后,效果如下
但是此时还是没有真正的操作到数据库,我们需要了解下一个schema的概念
Schema
Schema,即XML Schema,XSD (XML Schema Definition)是W3C于2001年5月发布的推荐标准,指出如何形式描述XML文档的元素。XSD是许多XML Schema 语言中的一支。XSD是首先分离于XML本身的schema语言,故获取W3C的推荐地位。
简单来说,schema就是如何描述一个文档,而在mongoose中,一个schema表示的是一个collection的映射,可以大概的理解为一个schema表示一个collection
Everything in Mongoose starts with a Schema. Each schema maps to a MongoDB collection and defines the shape of the documents within that collection.
schema 中field的类型有如下几种
StringNumberDateBufferBooleanMixedObjectIdArray
按照上面shell的测试线路,编写了以下的基础schema类型
const mongoose = require("mongoose");const Schema = mongoose.Schema;// 定义一个hero的collection,用于存放获取英雄卡片的时间记录var heroSchema = new Schema({ time: "string", timestampt: "Date", hero_name: "string", from: "string", from_index: "number"});
接下来。我们怎么使用这个schema,需要了解到model的概念
Model
Models 是从 Schema 编译来的构造函数。 它们的实例就代表着可以从数据库保存和读取的 documents。 从数据库创建和读取 document 的所有操作都是通过 model 进行的。
下面的代码中,请注意
model只是获取到collection的document。如果没有的时候会创建一个document,有的时候是直接去读取
在model的命名中,添加了第三个参数,是因为mongo的自动添加s原因,而前面的hero的collection是没有s,所以需要做collection名称的限制
为了方便,将db的find方法直接放在了conection方法中,正常开发是在需要调用数据库的时候查询的。
const mongoose = require("mongoose");const Schema = mongoose.Schema;// 定义一个hero的collection,用于存放获取英雄卡片的时间记录const schemaList = { "hero": new Schema({ time: "string", timestampt: "Date", hero_name: "string", from: "string", from_index: "number" })};const getModel = (name) => { if (schemaList[name]) { return mongoose.model(name, schemaList[name], name) }};module.exports = { getModel }
const mongoose = require('mongoose');const db = require("./schema");const dbLink = "mongodb://localhost/td_hero_shell";// 链接到mongodb// 获取链接的实体对象const connect = mongoose.connection// 连接的error处理connect.on("error", () => { console.log("mongodb链接错误============>");})// 只监听一次的连接打开connect.once('open', async () => { console.log("mongodb连接打开了========>") const data = await db.getModel("hero").find({}); console.log("当前查询mongodb的hero表的数据======>"); console.log(data);})mongoose.dbConnect = () => { mongoose.connect(dbLink);}module.exports = mongoose;
至此,事情结束,本来想继续写的,但是看了下字,三千多了,没必要写那么多,后续也会专门记一下关于mongodb的博客。
备注
启动mongodb的指令,可以根据自己的工具来提示
PS D:\mongodb\bin> mongod --dbpath E:/dbdatamongod : 无法将“mongod”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。所在位置 行:1 字符: 1+ mongod --dbpath E:/dbdata+ ~~~~~~ + CategoryInfo : ObjectNotFound: (mongod:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException
Suggestion [3,General]: 找不到命令 mongod,但它确实存在于当前位置。默认情况下,Windows PowerShell 不会从当前位置加载命令。如果信任此命令,请改为键入“.\mongod”。有关详细信息,请参阅 "get-help about_Command_Precedence"。PS D:\mongodb\bin> .\mongod --dbpath E:/dbdata
mongodb在6后面的版本中,都已经将mondo的shell抽离出来了,所以想要用旧的方式启动服务的时候,需要重新安装shell
退出shell的方式
输入exit,然后回车,就可以了