MongoDB初探

简介

MongoDB是一个流行的开源NoSQL文档型数据库,由若干JSON格式且具备schema的document组成,可以在MongoDB Atlas云平台使用,并且内置服务性能分析模块等,非常强大。

本文分为mongoDB核心概念介绍、mongoose介绍和express实战三个方面。

mongoDB核心概念

数据库常规概念回顾

每个database由多张table组成,每张table的构成如下:

image-20240508171015259

mongoDB architecture

document store

Mongo Instance

可以理解成一个server,管理多个database

database

MongoDB中的database指的是数据的物理容器,一个MongoDB服务器包含多个数据库,每个数据库内都有一套独立的文件系统

Relational and non relational databases

collection

collection是一组document的集合,通常可以被类比成关系型数据库中的表,不同的是collection没有schema约束,而document有schema。

Databases and Collections - MongoDB Manual v7.0

document

document是Field-Value键值对的集合(必须是JSON格式)。每个document都有动态schema结构,这意味着collection中每个document可能有截然不同的结构或fields,可能有相同的filed也可能没有

db.users是一个collection,通过调用insert方法向其中插入一个collection,或者通过insertMany插入多个collection

备注:一般来说不直接这样使用db,推荐使用mongoose连接和管理数据库,通过schema建立model,通过model操作对应数据

MongoDB Data Types & Field-Value Pairs | Studio 3T

Field-Value Pair

MongoDB Data Types & Field-Value Pairs | Studio 3T

mongoose介绍

mongoose是nodeJS环境下连接mongoDB的第三方库,是对数据库操作进行封装的对象模型工具,将数据库中的数据转换成javascript对象方便开发者使用,核心概念是schema和models

schema

mongoose中的一切都起源于一个schema,每个schema映射到MongoDB内collection中的document格式。

schema不仅定义了document的field和structure,还定义了文档实例方法、模型静态方法、复合索引

schema是动态的

schema甚至可以约束枚举

1
2
3
4
5
6
7
8
9
10
11
const UserSchema = mongoose.Schema(
{
name: {
type: 'String',
required: true,
min: 2,
max: 100,
},
...
},
);

models

使用schema定义可以创建我们需要的数据模型model,便于在controller层操作使用

1
2
// server/models/User.js
const User = mongoose.model('User', UserSchema);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// server/controller/general.js
import { User } from '../models/User.js';

export const getUser = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findById(id);
res.status(200).json(user);
} catch (error) {
res.status(404).json({
code: -1,
message: error.message,
});
}
};

模型静态方法

可以对通过schema创建的model进行操作,如findById、insertMany等方法

1
const user = await User.findById(id);
1
User.insertMany(dataUser); // dataUser是一个满足schema的对象数组

express+MongoDB+mongoose实战

0.预备工作

登录https://cloud.mongodb.com/建立database,可以使用azure或者aws的免费资源建立cluster

设置IP和User access白名单保证云端数据库的安全性

1.mongoose连接数据库

在根目录下新建.env文件存放环境变量如MONGO_URL、PORT,通过dotenv读取信息

1
2
3
4
5
6
7
8
9
10
11
12
13
dotenv.config(); // 将.env敏感信息注入到环境中、能被process.env访问
/* MONGOOSE SETUP */
const PORT = process.env.PORT || 9000;
mongoose
.connect(process.env.MONGO_URL)
.then(() => {
app.listen(PORT, () => {
console.log(`server is running at http://localhost:${PORT}`);
});
})
.catch((error) => {
console.log(error);
});

2.model层建立schema和collection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import mongoose from 'mongoose';

const UserSchema = mongoose.Schema(
{
name: {
type: 'String',
required: true,
min: 2,
max: 100,
},
email: {
type: 'String',
required: true,
unique: true,
max: 50,
},
password: {
type: 'String',
required: true,
min: 5,
},
city: String,
state: String,
country: String,
occupation: String,
phoneNumber: String,
transactions: Array,
role: {
type: 'String',
enum: ['user', 'admin', 'superadmin'],
default: 'admin',
},
},
{
timestamps: true,
}
);

export const User = mongoose.model('User', UserSchema);

3.controller层封装操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { User } from '../models/User.js';

export const getUser = async (req, res) => {
try {
const { id } = req.params;
const user = await User.findById(id);
res.status(200).json(user);
} catch (error) {
res.status(404).json({
code: -1,
message: error.message,
});
}
};

4.暴露后端API并测试

1
2
3
4
5
6
7
8
9
# server/routes/general.js
import express from 'express';
import { getUser } from '../controller/general.js';

const router = express.Router();

router.get('/user/:id', getUser);

export default router;
1
2
3
# server/index.js
import generaRoutes from './routes/general.js';
app.use('/general', generaRoutes);

访问http://localhost:5001/general/user/63701cc1f03239b7f700000e可以正确获取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"_id": "63701cc1f03239b7f700000e",
"name": "Shelly",
"email": "swelbeck12@ycombinator.com",
"password": "RSjzmAjnq",
"city": "Sangoleng",
"state": null,
"country": "ID",
"occupation": "Pharmacist",
"phoneNumber": "7036619983",
"transactions": [
"63701d74f03239d81e000027",
"63701d74f032396b8e00002c",
"63701d74f032396b8e000037",
"63701d74f03239d81e00002a",
"63701d74f03239c72c0001ba",
"63701d74f032399c00000151",
"63701d74f03239c72c0001a1"
],
"role": "superadmin",
"__v": 0,
"createdAt": "2024-05-08T07:06:12.736Z",
"updatedAt": "2024-05-08T07:06:12.736Z"
}

MongoDB初探
https://hugtyftg.github.io/2024/05/08/MongoDB初探/
作者
mmy@hugtyftg
发布于
2024年5月8日
许可协议