掌握文档数据库核心操作:CRUD、聚合管道与索引优化
MongoDB是全球最受欢迎的文档型NoSQL数据库,以其灵活的数据模型、出色的水平扩展能力和丰富的查询功能而闻名。与传统关系型数据库不同,MongoDB使用BSON(Binary JSON)格式存储数据,无需预定义表结构,让开发者能够快速迭代。本指南将全面介绍MongoDB的核心操作,帮助你快速上手。
| SQL概念 | MongoDB概念 | 说明 |
|---|---|---|
| Database | Database | 数据库,顶层容器 |
| Table | Collection | 集合,文档的容器 |
| Row | Document | 文档,BSON格式的记录 |
| Column | Field | 字段,键值对 |
| Index | Index | 索引,加速查询 |
| JOIN | $lookup | 关联查询 |
一个MongoDB文档示例:
{
"_id": ObjectId("6601a2b3e4f0a1b2c3d4e5f6"),
"name": "张三",
"email": "zhangsan@example.com",
"age": 28,
"skills": ["JavaScript", "Python", "MongoDB"],
"address": {
"city": "北京",
"district": "海淀区"
},
"createdAt": ISODate("2026-04-01T08:00:00Z")
}
// 插入单个文档
db.users.insertOne({
name: "李四",
email: "lisi@example.com",
age: 25
});
// 批量插入
db.users.insertMany([
{ name: "王五", email: "wangwu@example.com", age: 30 },
{ name: "赵六", email: "zhaoliu@example.com", age: 22 },
{ name: "孙七", email: "sunqi@example.com", age: 35 }
]);
// 查询所有文档
db.users.find();
// 条件查询
db.users.find({ age: { $gte: 25 } }); // 年龄 >= 25
db.users.find({ skills: "JavaScript" }); // 包含某技能
db.users.find({ name: /张/ }); // 正则匹配
// 比较操作符:$eq, $ne, $gt, $gte, $lt, $lte, $in, $nin
// 逻辑操作符:$and, $or, $not, $nor
// 元素操作符:$exists, $type
db.users.find({
$or: [
{ age: { $lt: 20 } },
{ age: { $gt: 30 } },
{ skills: { $exists: true } }
]
});
// 投影(只返回指定字段)
db.users.find({}, { name: 1, email: 1, _id: 0 });
// 排序和分页
db.users.find()
.sort({ age: -1 }) // 按年龄降序
.skip(10) // 跳过前10条
.limit(5); // 返回5条
// 更新单个文档
db.users.updateOne(
{ name: "张三" },
{ $set: { age: 29 }, $inc: { loginCount: 1 } }
);
// 更新多个文档
db.users.updateMany(
{ status: "active" },
{ $set: { lastActive: new Date() } }
);
// 更新操作符
// $set - 设置字段值
// $unset - 删除字段
// $inc - 数值递增
// $push - 向数组添加元素
// $pull - 从数组移除元素
// $addToSet - 数组去重添加
// $rename - 重命名字段
db.users.updateOne(
{ name: "张三" },
{
$push: { skills: "Docker" },
$pull: { skills: "HTML" },
$inc: { score: 10 }
}
);
// upsert:不存在则插入
db.users.updateOne(
{ email: "new@example.com" },
{ $set: { name: "新用户", age: 20 } },
{ upsert: true }
);
// 删除单个文档
db.users.deleteOne({ name: "张三" });
// 删除多个文档
db.users.deleteMany({ age: { $lt: 18 } });
// ⚠️ 删除所有文档(危险!)
// db.users.deleteMany({});
聚合管道是MongoDB最强大的数据处理功能,通过多个阶段组成管道,对文档进行转换、过滤和计算。
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $group: {
_id: "$userId",
totalAmount: { $sum: "$amount" },
orderCount: { $sum: 1 },
avgAmount: { $avg: "$amount" }
}},
{ $sort: { totalAmount: -1 } },
{ $limit: 10 }
]);
| 阶段 | 功能 | 类比SQL |
|---|---|---|
| $match | 过滤文档 | WHERE |
| $group | 分组聚合 | GROUP BY |
| $sort | 排序 | ORDER BY |
| $limit / $skip | 分页 | LIMIT / OFFSET |
| $project | 字段投影 | SELECT |
| $unwind | 展开数组 | 无直接类比 |
| $lookup | 左外连接 | LEFT JOIN |
| $count | 计数 | COUNT(*) |
// 统计各分类的商品销售额
db.orders.aggregate([
{ $unwind: "$items" },
{ $lookup: {
from: "products",
localField: "items.productId",
foreignField: "_id",
as: "product"
}},
{ $unwind: "$product" },
{ $group: {
_id: "$product.category",
totalSales: { $sum: { $multiply: ["$items.quantity", "$items.price"] } },
productCount: { $sum: 1 }
}},
{ $sort: { totalSales: -1 } }
]);
索引是提升查询性能的核心手段。没有索引的集合只能通过全表扫描(COLLSCAN)查找数据。
// 单字段索引
db.users.createIndex({ email: 1 });
// 复合索引(遵循ESR原则:Equality → Sort → Range)
db.users.createIndex({ status: 1, createdAt: -1 });
// 唯一索引
db.users.createIndex({ email: 1 }, { unique: true });
// 文本索引(全文搜索)
db.articles.createIndex({ title: "text", content: "text" });
// TTL索引(自动删除过期文档)
db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 });
// 查看索引
db.users.getIndexes();
// 查看查询执行计划
db.users.find({ email: "test@example.com" }).explain("executionStats");
需要在线格式化JSON数据?试试我们的 JSON格式化工具,支持语法高亮和压缩功能。
MongoDB是文档型NoSQL数据库,使用BSON格式存储数据,没有固定表结构,适合灵活的数据模型;MySQL是关系型数据库,使用表格存储,需要预定义schema,适合结构化数据和复杂事务。
聚合管道是MongoDB的数据处理框架,通过多个阶段($match、$group、$sort等)组成的管道对文档进行转换和计算,类似SQL的GROUP BY但功能更强大。
MongoDB适合内容管理系统、实时分析、物联网数据存储、用户画像、日志系统、社交应用等需要灵活schema和高扩展性的场景。不适合需要复杂事务和强一致性的金融系统。
通过创建合适的索引(单字段索引、复合索引、文本索引等)、使用投影减少返回字段、合理设计分片策略、以及使用explain()分析查询计划来优化性能。