MongoDB 基础
问题
MongoDB 的文档模型是什么?查询和聚合怎么用?
答案
核心概念对比
| SQL 概念 | MongoDB 概念 |
|---|---|
| Database | Database |
| Table | Collection |
| Row | Document(JSON/BSON) |
| Column | Field |
| JOIN | $lookup / 嵌套文档 |
| PRIMARY KEY | _id(自动生成) |
CRUD 操作
mongodb-crud.ts
import { MongoClient, ObjectId } from 'mongodb';
const client = new MongoClient('mongodb://localhost:27017');
const db = client.db('myapp');
const users = db.collection('users');
// 插入
await users.insertOne({
name: 'Alice',
email: 'alice@example.com',
tags: ['developer', 'gamer'],
address: { city: '北京', district: '朝阳' },
});
// 查询
const user = await users.findOne({ email: 'alice@example.com' });
const devs = await users.find({ tags: 'developer' }).sort({ name: 1 }).limit(10).toArray();
// 更新
await users.updateOne(
{ _id: new ObjectId('...') },
{
$set: { name: 'Bob' },
$push: { tags: 'writer' },
$inc: { loginCount: 1 },
},
);
// 删除
await users.deleteOne({ _id: new ObjectId('...') });
聚合管道
aggregation.ts
// 统计每个城市的用户数和平均年龄
const result = await users.aggregate([
{ $match: { age: { $gte: 18 } } }, // 过滤
{ $group: { // 分组
_id: '$address.city',
count: { $sum: 1 },
avgAge: { $avg: '$age' },
}},
{ $sort: { count: -1 } }, // 排序
{ $limit: 10 }, // 限制
]).toArray();
// $lookup 实现 JOIN
const orders = await db.collection('orders').aggregate([
{
$lookup: {
from: 'users', // 关联的集合
localField: 'userId', // 本集合的字段
foreignField: '_id', // 关联集合的字段
as: 'user', // 结果字段名
},
},
{ $unwind: '$user' }, // 展开数组
]).toArray();
文档设计:嵌套 vs 引用
schema-design.ts
// 嵌套(一对少、读多写少)
interface BlogPost {
title: string;
content: string;
comments: Array<{ // 嵌套在文档内
author: string;
text: string;
createdAt: Date;
}>;
}
// 引用(一对多、独立更新频繁)
interface Order {
userId: ObjectId; // 引用 users 集合
items: Array<{
productId: ObjectId; // 引用 products 集合
quantity: number;
price: number;
}>;
}
嵌套 vs 引用选择
- 嵌套:数据一起读取、子文档数量有限、子文档不需要独立查询
- 引用:数据需要独立访问、子文档数量很大、需要跨文档查询
常见面试问题
Q1: MongoDB 的索引和 MySQL 有什么区别?
答案:
MongoDB 也使用 B 树索引,支持:
- 单字段索引、复合索引(同样遵循最左前缀)
- 文本索引(全文搜索)
- 地理空间索引(2dsphere)
- TTL 索引(自动过期删除)
Q2: MongoDB 支持事务吗?
答案:
MongoDB 4.0+ 支持多文档事务,4.2+ 支持分布式事务。但过度使用事务会降低性能,应优先通过文档设计减少事务需求。
Q3: Mongoose 和原生 MongoDB 驱动怎么选?
答案:
- Mongoose:提供 Schema 定义、校验、中间件、虚拟属性,适合需要严格 Schema 的项目
- 原生驱动:更轻量、更灵活、性能更高
相关链接
- SQL vs NoSQL - 数据库选型
- ORM 框架对比 - Mongoose 等 ORM