MongoDB的基本操作(适配Node.js全栈项目)

在 Node.js 全栈项目中,MongoDB 作为非关系型数据库(NoSQL),常被用于存储结构灵活的文档数据(如用户信息、文章内容、日志等)。以下结合 Node.js 生态(使用官方驱动
mongodb
或 ODM 工具
Mongoose
),详解 MongoDB 的基本操作及适配项目的实践。

一、环境准备

安装 MongoDB:本地部署或使用云服务(如 MongoDB Atlas),确保服务启动(默认端口
27017
)。Node.js 依赖
官方驱动:
npm install mongodb
(适合原生操作)。Mongoose(推荐):
npm install mongoose
(基于官方驱动的 ODM 工具,提供 schema 验证、中间件等功能)。

二、核心概念(与 SQL 对比)

MongoDB SQL 说明
Database Database 数据库(独立的存储单元)
Collection Table 集合(类似表,存储多个文档)
Document Row 文档(类似行,JSON 格式的数据记录)
Field Column 字段(文档中的键值对)
ObjectId Primary Key 文档唯一标识(默认自动生成)

三、使用 Mongoose 操作 MongoDB(推荐)

Mongoose 是 Node.js 中最流行的 MongoDB ODM 工具,通过
Schema
定义数据结构,
Model
操作集合,简化开发。

1. 连接数据库

// db.js
const mongoose = require('mongoose');

// 连接本地 MongoDB(数据库名:myapp)
mongoose.connect('mongodb://localhost:27017/myapp', {
  useNewUrlParser: true,
  useUnifiedTopology: true
})
.then(() => console.log('MongoDB 连接成功'))
.catch(err => console.error('连接失败:', err));

module.exports = mongoose;
2. 定义 Schema 与 Model


Schema
用于约束文档结构(字段类型、默认值、验证规则等),
Model
是 Schema 的实例化,对应 MongoDB 的 Collection。


// models/User.js
const mongoose = require('../db');

// 定义用户 Schema
const userSchema = new mongoose.Schema({
  username: {
    type: String,       // 字段类型
    required: true,     // 必传
    unique: true,       // 唯一(不可重复)
    trim: true          // 自动去除首尾空格
  },
  age: {
    type: Number,
    min: 0,             // 最小值验证
    default: 0          // 默认值
  },
  email: {
    type: String,
    match: /^[w-]+@([w-]+.)+[w-]+$/, // 邮箱格式验证
    required: true
  },
  createdAt: {
    type: Date,
    default: Date.now   // 默认当前时间
  }
});

// 创建 Model(对应集合:users,自动小写并复数化)
const User = mongoose.model('User', userSchema);

module.exports = User;
3. 基本 CRUD 操作
(1)创建文档(Create)

const User = require('./models/User');

// 方式 1:实例化后保存
const user = new User({
  username: 'alice',
  age: 25,
  email: 'alice@example.com'
});
await user.save(); // 返回保存后的文档(含 _id)

// 方式 2:直接通过 Model 创建
const user = await User.create({
  username: 'bob',
  age: 30,
  email: 'bob@example.com'
});
(2)查询文档(Read)

// 1. 查询所有文档
const allUsers = await User.find(); // 返回数组

// 2. 条件查询(年龄 > 20)
const adults = await User.find({ age: { $gt: 20 } });

// 3. 投影(只返回 username 和 email,不返回 _id)
const userFields = await User.find({}, { username: 1, email: 1, _id: 0 });

// 4. 排序(按 age 升序,-1 为降序)
const sortedUsers = await User.find().sort({ age: 1 });

// 5. 分页(跳过前 10 条,取 5 条)
const paginatedUsers = await User.find().skip(10).limit(5);

// 6. 查询单个文档(按条件,返回第一个)
const user = await User.findOne({ username: 'alice' });

// 7. 按 ID 查询
const user = await User.findById('6555a7b3f2d4e8c3d8f7e6d5');
(3)更新文档(Update)

// 1. 更新单个文档(按条件,返回更新后的文档)
const updatedUser = await User.findOneAndUpdate(
  { username: 'alice' }, // 条件
  { age: 26 },           // 更新内容
  { new: true }          // 选项:返回更新后的数据(默认返回更新前)
);

// 2. 更新多个文档(年龄 < 18 的设为 18)
const result = await User.updateMany(
  { age: { $lt: 18 } },
  { age: 18 }
);
// result 包含:n(匹配数量)、nModified(修改数量)等

// 3. 按 ID 更新
const updatedUser = await User.findByIdAndUpdate(
  '6555a7b3f2d4e8c3d8f7e6d5',
  { email: 'new-alice@example.com' },
  { new: true }
);
(4)删除文档(Delete)

// 1. 删除单个文档(按条件)
const deletedUser = await User.findOneAndDelete({ username: 'bob' });

// 2. 删除多个文档(年龄 > 50)
const result = await User.deleteMany({ age: { $gt: 50 } });

// 3. 按 ID 删除
const deletedUser = await User.findByIdAndDelete('6555a7b3f2d4e8c3d8f7e6d5');
4. 高级查询(条件操作符)

MongoDB 提供丰富的查询操作符,满足复杂条件查询:

操作符 说明 示例(查询条件)

$eq
等于
{ age: { $eq: 25 } }

$ne
不等于
{ age: { $ne: 25 } }

$gt
/
$lt
大于 / 小于
{ age: { $gt: 20, $lt: 30 } }

$in
在数组中
{ username: { $in: ['alice', 'bob'] } }

$regex
正则匹配
{ email: { $regex: /@example.com$/ } }

$and
/
$or
逻辑与 / 或
{ $and: [{ age: { $gt: 20 } }, { email: { $exists: true } }] }

四、使用官方驱动
mongodb
操作(原生方式)

若需更灵活的原生操作,可直接使用
mongodb
驱动:


const { MongoClient } = require('mongodb');

// 连接客户端
const client = new MongoClient('mongodb://localhost:27017');
await client.connect();

// 获取数据库和集合
const db = client.db('myapp');
const usersCollection = db.collection('users');

// 1. 创建文档
await usersCollection.insertOne({ username: 'carol', age: 28 });

// 2. 查询文档
const user = await usersCollection.findOne({ username: 'carol' });

// 3. 更新文档
await usersCollection.updateOne(
  { username: 'carol' },
  { $set: { age: 29 } }
);

// 4. 删除文档
await usersCollection.deleteOne({ username: 'carol' });

// 关闭连接
await client.close();

五、适配 Node.js 全栈项目的实践建议

分层设计

模型层(
models
):定义 Mongoose Schema 和 Model。服务层(
services
):封装数据库操作逻辑(如
userService.getById()
)。控制器层(
controllers
):处理 HTTP 请求,调用服务层方法返回结果。


// services/userService.js
const User = require('../models/User');
exports.getUserById = async (id) => {
  return await User.findById(id);
};

// controllers/userController.js
const userService = require('../services/userService');
exports.getUser = async (req, res) => {
  const user = await userService.getUserById(req.params.id);
  res.json(user);
};

错误处理
捕获数据库操作错误(如重复键、验证失败),返回友好的 HTTP 错误:


try {
  await User.create({ username: 'alice', email: 'invalid-email' });
} catch (err) {
  if (err.code === 11000) { // 重复键错误
    return res.status(400).json({ error: '用户名已存在' });
  }
  if (err.name === 'ValidationError') { // 验证错误
    return res.status(400).json({ error: err.message });
  }
}

索引优化
对高频查询字段创建索引(如
username

email
),提升查询性能:


// 在 Schema 中定义索引
userSchema.index({ username: 1 }); // 1 为升序索引
userSchema.index({ email: 1 });

批量操作
对大量数据使用批量插入/更新(
insertMany

bulkWrite
),减少数据库交互次数:


// 批量插入
await User.insertMany([
  { username: 'user1', email: 'user1@test.com' },
  { username: 'user2', email: 'user2@test.com' }
]);

总结

MongoDB 在 Node.js 项目中通过 Mongoose 可简化操作,核心是通过
Schema
约束数据、
Model
执行 CRUD。适配全栈项目时,需注意分层设计、错误处理和性能优化(如索引、批量操作)。对于结构灵活、迭代快速的项目(如社交应用、内容管理系统),MongoDB 是高效的选择。

© 版权声明

相关文章

暂无评论

none
暂无评论...