简介
MongoDB是一个流行的开源NoSQL文档型数据库,由若干JSON格式且具备schema的document组成,可以在MongoDB Atlas云平台使用,并且内置服务性能分析模块等,非常强大。
本文分为mongoDB核心概念介绍、mongoose介绍和express实战三个方面。
mongoDB核心概念
数据库常规概念回顾
每个database由多张table组成,每张table的构成如下:
mongoDB architecture
Mongo Instance
可以理解成一个server,管理多个database
database
MongoDB中的database指的是数据的物理容器,一个MongoDB服务器包含多个数据库,每个数据库内都有一套独立的文件系统
collection
collection是一组document的集合,通常可以被类比成关系型数据库中的表,不同的是collection没有schema约束,而document有schema。
document
document是Field-Value键值对的集合(必须是JSON格式)。每个document都有动态schema结构,这意味着collection中每个document可能有截然不同的结构或fields,可能有相同的filed也可能没有
db.users是一个collection,通过调用insert方法向其中插入一个collection,或者通过insertMany插入多个collection
备注:一般来说不直接这样使用db,推荐使用mongoose连接和管理数据库,通过schema建立model,通过model操作对应数据
Field-Value Pair
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
| const User = mongoose.model('User', UserSchema);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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);
|
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();
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" }
|