MongoDB 是一个面向文档的 NoSQL 数据库,使用 BSON(Binary JSON)作为数据格式。相比传统关系型数据库的表-行结构,MongoDB 采用集合-文档的层次结构,更适合存储半结构化数据和快速迭代场景。
1. 核心概念对比
| 关系型数据库 | MongoDB | 说明 |
|---|---|---|
| Database | Database | 逻辑数据库 |
| Table | Collection | 集合(无固定 schema) |
| Row | Document | BSON 文档(最大 16MB) |
| Column | Field | 字段 |
| Index | Index | 索引 |
| Primary Key | _id | 默认 ObjectId |
2. BSON 数据类型
{
_id: ObjectId("64a1b2c3d4e5f6a7b8c9d0e1"), // 12字节唯一ID
name: "Alice", // String
age: 30, // Int32
salary: 12500.50, // Double
isActive: true, // Boolean
tags: ["developer", "admin"], // Array
address: { // Embedded Document
city: "Beijing",
zip: "100000"
},
createdAt: ISODate("2024-01-15T08:00:00Z"), // Date
metadata: null, // Null
profile: BinData(0, "base64string"), // Binary
config: undefined // Undefined (避免使用)
}
ObjectId 结构:
64a1b2c3 d4e5f6 a7b8c9 d0e1
timestamp machine pid counter
(4B) (3B) (2B) (3B)
3. 数据库与集合操作
// 创建/切换数据库
use ecommerce;
// 查看集合
db.getCollectionNames();
// 创建集合(带选项)
db.createCollection("products", {
capped: true, // 固定大小集合
size: 5242880, // 5MB
max: 5000 // 最多5000条文档
});
// 删除集合
db.products.drop();
// 查看集合统计
db.products.stats();
4. CRUD 操作
4.1 Create(插入)
// 插入单条
db.users.insertOne({
name: "Alice",
email: "alice@example.com",
age: 30,
createdAt: new Date()
});
// 插入多条(无序,遇到错误继续)
db.users.insertMany([
{ name: "Bob", age: 25, tags: ["new"] },
{ name: "Charlie", age: 35, tags: ["vip"] }
], { ordered: false });
// 原子递增插入
db.counters.findOneAndUpdate(
{ _id: "orderId" },
{ $inc: { seq: 1 } },
{ upsert: true, returnDocument: "after" }
);
4.2 Read(查询)
// 精确匹配
db.users.find({ age: 30 });
// 比较操作符
db.products.find({
price: { $gte: 100, $lte: 500 },
stock: { $gt: 0 }
});
// 逻辑组合
db.users.find({
$and: [
{ age: { $gte: 18 } },
{ $or: [
{ status: "active" },
{ vip: true }
]}
]
});
// 数组查询
db.users.find({ tags: { $in: ["developer", "admin"] } }); // 包含任一
db.users.find({ tags: { $all: ["developer", "mongodb"] } }); // 包含全部
db.users.find({ tags: { $size: 2 } }); // 数组长度
// 元素级匹配(数组中的对象)
db.orders.find({ items: { $elemMatch: { sku: "SKU001", qty: { $gt: 5 } } } });
// 投影(只返回指定字段)
db.users.find({}, { name: 1, email: 1, _id: 0 });
// 排序+分页
db.users.find()
.sort({ createdAt: -1 }) // 降序
.skip(20) // 跳过前20条
.limit(10); // 取10条
比较操作符速查:
| 操作符 | 含义 |
|---|---|
$eq | 等于 |
$ne | 不等于 |
$gt / $gte | 大于/大于等于 |
$lt / $lte | 小于/小于等于 |
$in / $nin | 在/不在数组中 |
$regex | 正则匹配 |
$exists | 字段是否存在 |
$type | 字段类型匹配 |
4.3 Update(更新)
// 更新单条
db.users.updateOne(
{ name: "Alice" },
{ $set: { age: 31, updatedAt: new Date() } }
);
// 更新多条
db.users.updateMany(
{ status: "pending" },
{ $set: { status: "active" }, $inc: { loginCount: 1 } }
);
// 更新操作符
{ $set: { field: value } } // 设置字段
{ $unset: { field: "" } } // 删除字段
{ $inc: { counter: 1 } } // 递增
{ $mul: { price: 1.1 } } // 相乘
{ $push: { tags: "new-tag" } } // 数组尾部添加
{ $addToSet: { tags: "new-tag" } } // 数组添加(去重)
{ $pull: { tags: "old-tag" } } // 数组移除
{ $pop: { tags: 1 } } // 数组弹出尾部(-1为头部)
{ $rename: { oldName: "newName" } } // 重命名字段
4.4 Delete(删除)
// 删除单条
db.users.deleteOne({ _id: ObjectId("64a1b2c3d4e5f6a7b8c9d0e1") });
// 删除多条
db.logs.deleteMany({ createdAt: { $lt: new Date(Date.now() - 30*24*60*60*1000) } });
// 清空集合(比 deleteMany 快)
db.users.deleteMany({});
// 删除集合并回收空间
db.users.drop();
5. 批量操作与优化
// 有序批量写入(默认): 遇到错误停止
db.users.bulkWrite([
{ insertOne: { document: { name: "User1" } } },
{ updateOne: { filter: { name: "Alice" }, update: { $set: { age: 32 } } } },
{ deleteOne: { filter: { name: "Bob" } } }
]);
// 游标遍历(大数据量避免内存溢出)
const cursor = db.largeCollection.find().batchSize(1000);
cursor.forEach(doc => {
process(doc);
});
// explain 分析查询性能
db.users.find({ email: "alice@example.com" }).explain("executionStats");
延伸阅读
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。