名称:mongodb 描述:MongoDB实施指南 - 一个文档数据库平台,具有CRUD操作、聚合管道、索引、复制、分片、搜索能力和全面安全性。适用于使用MongoDB数据库、设计模式、编写查询、优化性能、配置部署(Atlas/自管理/Kubernetes)、实施安全或通过15+官方驱动程序集成应用程序时使用。(项目)
MongoDB 代理技能
一个全面的MongoDB工作指南 - 一个文档导向的数据库平台,提供强大的查询、水平扩展、高可用性和企业级安全性。
何时使用此技能
当您需要时使用此技能:
- 设计MongoDB模式和数据模型
- 编写CRUD操作和复杂查询
- 构建聚合管道进行数据转换
- 使用索引优化查询性能
- 配置复制以实现高可用性
- 设置分片以实现水平扩展
- 实施安全(认证、授权、加密)
- 部署MongoDB(Atlas、自管理、Kubernetes)
- 通过15+官方驱动程序集成MongoDB与应用程序
- 故障排除性能问题或错误
- 实施Atlas搜索或向量搜索
- 处理时间序列数据或变更流
文档覆盖范围
此技能综合了24,618个文档链接,横跨172个主要MongoDB部分,覆盖:
- MongoDB版本5.0至8.1(即将发布)
- 15+官方驱动程序语言
- 50+集成工具(Kafka、Spark、BI连接器、Kubernetes操作符)
- 完整的部署范围(Atlas云、自管理、Kubernetes)
I. 核心数据库操作
A. CRUD操作
读取操作
// 查找文档
db.collection.find({ status: "active" })
db.collection.findOne({ _id: ObjectId("...") })
// 查询运算符
db.users.find({ age: { $gte: 18, $lt: 65 } })
db.posts.find({ tags: { $in: ["mongodb", "database"] } })
db.products.find({ price: { $exists: true } })
// 投影(选择特定字段)
db.users.find({ status: "active" }, { name: 1, email: 1 })
// 游标操作
db.collection.find().sort({ createdAt: -1 }).limit(10).skip(20)
写入操作
// 插入
db.collection.insertOne({ name: "Alice", age: 30 })
db.collection.insertMany([{ name: "Bob" }, { name: "Charlie" }])
// 更新
db.users.updateOne(
{ _id: userId },
{ $set: { status: "verified" } }
)
db.users.updateMany(
{ lastLogin: { $lt: cutoffDate } },
{ $set: { status: "inactive" } }
)
// 替换整个文档
db.users.replaceOne({ _id: userId }, newUserDoc)
// 删除
db.users.deleteOne({ _id: userId })
db.users.deleteMany({ status: "deleted" })
// 更新或插入(如果不存在)
db.users.updateOne(
{ email: "user@example.com" },
{ $set: { name: "User", lastSeen: new Date() } },
{ upsert: true }
)
原子操作
// 递增计数器
db.posts.updateOne(
{ _id: postId },
{ $inc: { views: 1 } }
)
// 添加到数组(如果不存在)
db.users.updateOne(
{ _id: userId },
{ $addToSet: { interests: "mongodb" } }
)
// 推送到数组
db.posts.updateOne(
{ _id: postId },
{ $push: { comments: { author: "Alice", text: "Great!" } } }
)
// 原子查找和修改
db.counters.findAndModify({
query: { _id: "sequence" },
update: { $inc: { value: 1 } },
new: true,
upsert: true
})
B. 查询运算符(100+)
比较运算符
$eq, $ne, $gt, $gte, $lt, $lte
$in, $nin
逻辑运算符
$and, $or, $not, $nor
// 示例
db.products.find({
$and: [
{ price: { $gte: 100 } },
{ stock: { $gt: 0 } }
]
})
数组运算符
$all, $elemMatch, $size
$firstN, $lastN, $maxN, $minN
// 示例:查找具有所有标签的文档
db.posts.find({ tags: { $all: ["mongodb", "database"] } })
// 匹配具有多个条件的数组元素
db.products.find({
reviews: {
$elemMatch: { rating: { $gte: 4 }, verified: true }
}
})
存在性和类型
$exists, $type
// 查找具有可选字段的文档
db.users.find({ phoneNumber: { $exists: true } })
// 类型检查
db.data.find({ value: { $type: "string" } })
C. 聚合管道
MongoDB最强大的功能,用于数据转换和分析。
核心管道阶段(40+)
db.orders.aggregate([
// 阶段1:过滤文档
{ $match: { status: "completed", total: { $gte: 100 } } },
// 阶段2:与客户连接
{ $lookup: {
from: "customers",
localField: "customerId",
foreignField: "_id",
as: "customer"
}},
// 阶段3:展开数组
{ $unwind: "$items" },
// 阶段4:分组和聚合
{ $group: {
_id: "$items.category",
totalRevenue: { $sum: "$items.total" },
orderCount: { $sum: 1 },
avgOrderValue: { $avg: "$total" }
}},
// 阶段5:排序结果
{ $sort: { totalRevenue: -1 } },
// 阶段6:限制结果
{ $limit: 10 },
// 阶段7:重塑输出
{ $project: {
category: "$_id",
revenue: "$totalRevenue",
orders: "$orderCount",
avgValue: { $round: ["$avgOrderValue", 2] },
_id: 0
}}
])
常见管道模式
基于时间的聚合:
db.events.aggregate([
{ $match: { timestamp: { $gte: startDate, $lt: endDate } } },
{ $group: {
_id: {
year: { $year: "$timestamp" },
month: { $month: "$timestamp" },
day: { $dayOfMonth: "$timestamp" }
},
count: { $sum: 1 }
}}
])
多面搜索(多个聚合):
db.products.aggregate([
{ $match: { category: "electronics" } },
{ $facet: {
priceRanges: [
{ $bucket: {
groupBy: "$price",
boundaries: [0, 100, 500, 1000, 5000],
default: "5000+",
output: { count: { $sum: 1 } }
}}
],
topBrands: [
{ $group: { _id: "$brand", count: { $sum: 1 } } },
{ $sort: { count: -1 } },
{ $limit: 5 }
],
avgPrice: [
{ $group: { _id: null, avg: { $avg: "$price" } } }
]
}}
])
窗口函数:
db.sales.aggregate([
{ $setWindowFields: {
partitionBy: "$region",
sortBy: { date: 1 },
output: {
runningTotal: { $sum: "$amount", window: { documents: ["unbounded", "current"] } },
movingAvg: { $avg: "$amount", window: { documents: [-7, 0] } }
}
}}
])
聚合运算符(150+)
数学运算符:
$add, $subtract, $multiply, $divide, $mod
$abs, $ceil, $floor, $round, $sqrt, $pow
$log, $log10, $ln, $exp
字符串运算符:
$concat, $substr, $toLower, $toUpper
$trim, $ltrim, $rtrim, $split
$regexMatch, $regexFind, $regexFindAll
数组运算符:
$arrayElemAt, $slice, $first, $last, $reverse
$sortArray, $filter, $map, $reduce
$zip, $concatArrays
日期/时间运算符:
$dateAdd, $dateDiff, $dateFromString, $dateToString
$dayOfMonth, $month, $year, $dayOfWeek
$week, $hour, $minute, $second
类型转换:
$toInt, $toString, $toDate, $toDouble
$toDecimal, $toObjectId, $toBool
II. 索引和性能
A. 索引类型
单字段索引
db.users.createIndex({ email: 1 }) // 升序
db.posts.createIndex({ createdAt: -1 }) // 降序
复合索引
// 顺序重要!索引在 { status: 1, createdAt: -1 }
db.orders.createIndex({ status: 1, createdAt: -1 })
// 支持查询:
// - { status: "..." }
// - { status: "...", createdAt: ... }
// 不有效支持:{ createdAt: ... } 单独
文本索引(全文搜索)
db.articles.createIndex({ title: "text", body: "text" })
// 搜索
db.articles.find({ $text: { $search: "mongodb database" } })
// 带有相关性分数
db.articles.find(
{ $text: { $search: "mongodb" } },
{ score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } })
地理空间索引
// 2dsphere用于类地球几何
db.places.createIndex({ location: "2dsphere" })
// 查找附近
db.places.find({
location: {
$near: {
$geometry: { type: "Point", coordinates: [lon, lat] },
$maxDistance: 5000 // 米
}
}
})
通配符索引
// 索引子文档中的所有字段
db.products.createIndex({ "attributes.$**": 1 })
// 支持对属性下任何字段的查询
db.products.find({ "attributes.color": "red" })
部分索引
// 仅索引匹配过滤器的文档
db.orders.createIndex(
{ customerId: 1 },
{ partialFilterExpression: { status: "active" } }
)
TTL索引(自动删除)
// 在创建后24小时删除文档
db.sessions.createIndex(
{ createdAt: 1 },
{ expireAfterSeconds: 86400 }
)
哈希索引(用于分片)
db.users.createIndex({ userId: "hashed" })
B. 查询优化
解释查询计划
// 基本解释
db.users.find({ email: "user@example.com" }).explain()
// 执行统计(显示实际性能)
db.users.find({ age: { $gte: 18 } }).explain("executionStats")
// 检查关键指标:
// - executionTimeMillis
// - totalDocsExamined vs. nReturned(应接近)
// - stage: "IXSCAN"(使用索引)vs. "COLLSCAN"(全扫描 - 不好)
覆盖查询
// 创建索引
db.users.createIndex({ email: 1, name: 1 })
// 查询被索引覆盖(无需文档获取)
db.users.find(
{ email: "user@example.com" },
{ email: 1, name: 1, _id: 0 } // 仅投影索引字段
)
索引提示
// 强制特定索引
db.users.find({ status: "active", city: "NYC" })
.hint({ status: 1, createdAt: -1 })
索引管理
// 列出所有索引
db.collection.getIndexes()
// 删除索引
db.collection.dropIndex("indexName")
// 隐藏索引(在删除前测试)
db.collection.hideIndex("indexName")
db.collection.unhideIndex("indexName")
// 索引统计
db.collection.aggregate([{ $indexStats: {} }])
III. 数据建模模式
A. 关系模式
一对一(嵌入)
// 具有单个地址的用户
{
_id: ObjectId("..."),
name: "Alice",
email: "alice@example.com",
address: {
street: "123 Main St",
city: "NYC",
zipcode: "10001"
}
}
一对少(嵌入数组)
// 博客文章与评论(< 100评论)
{
_id: ObjectId("..."),
title: "MongoDB指南",
comments: [
{ author: "Bob", text: "Great post!", date: ISODate("...") },
{ author: "Charlie", text: "Thanks!", date: ISODate("...") }
]
}
一对多(引用)
// 作者集合
{ _id: ObjectId("author1"), name: "Alice" }
// 书籍集合(每个作者多本书)
{ _id: ObjectId("book1"), title: "Book 1", authorId: ObjectId("author1") }
{ _id: ObjectId("book2"), title: "Book 2", authorId: ObjectId("author1") }
多对多(引用数组)
// 用户集合
{
_id: ObjectId("user1"),
name: "Alice",
groupIds: [ObjectId("group1"), ObjectId("group2")]
}
// 组集合
{
_id: ObjectId("group1"),
name: "MongoDB用户",
memberIds: [ObjectId("user1"), ObjectId("user2")]
}
B. 高级模式
时间序列模式
// 高频传感器数据
{
_id: ObjectId("..."),
sensorId: "sensor-123",
timestamp: ISODate("2025-01-01T00:00:00Z"),
readings: [
{ time: 0, temp: 23.5, humidity: 45 },
{ time: 60, temp: 23.6, humidity: 46 },
{ time: 120, temp: 23.4, humidity: 45 }
]
}
// 创建时间序列集合
db.createCollection("sensor_data", {
timeseries: {
timeField: "timestamp",
metaField: "sensorId",
granularity: "minutes"
}
})
计算模式(缓存结果)
// 用户文档带有预计算统计
{
_id: ObjectId("..."),
username: "alice",
stats: {
postCount: 150,
followerCount: 2500,
lastUpdated: ISODate("...")
}
}
// 定期或用触发器更新统计
模式版本控制
// 支持模式演变
{
_id: ObjectId("..."),
schemaVersion: 2,
// v2字段
name: { first: "Alice", last: "Smith" },
// 迁移代码处理v1格式
}
C. 模式验证
db.createCollection("users", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["email", "name"],
properties: {
email: {
bsonType: "string",
pattern: "^.+@.+$",
description: "must be a valid email"
},
age: {
bsonType: "int",
minimum: 0,
maximum: 120
},
status: {
enum: ["active", "inactive", "pending"]
}
}
}
},
validationLevel: "strict", // 或 "moderate"
validationAction: "error" // 或 "warn"
})
IV. 复制和高可用性
A. 副本集
架构:
- 主节点:接受写入,复制到从节点
- 从节点:复制主节点的操作日志,可提供读取
- 仲裁节点:在选举中投票,不保存数据
配置:
rs.initiate({
_id: "myReplicaSet",
members: [
{ _id: 0, host: "mongo1:27017" },
{ _id: 1, host: "mongo2:27017" },
{ _id: 2, host: "mongo3:27017" }
]
})
// 检查状态
rs.status()
// 添加成员
rs.add("mongo4:27017")
// 移除成员
rs.remove("mongo4:27017")
B. 写入关注
控制写入操作的确认:
// 等待大多数确认(持久)
db.users.insertOne(
{ name: "Alice" },
{ writeConcern: { w: "majority", wtimeout: 5000 } }
)
// 常见级别:
// w: 1 - 主节点确认(默认)
// w: "majority" - 多数节点确认(生产推荐)
// w: <number> - 特定节点数
// w: 0 - 无确认(发射后不管)
C. 读取偏好
控制读取从哪里提供:
// 选项:
// - primary(默认):仅从主节点读取
// - primaryPreferred:主节点如果可用,否则从节点
// - secondary:仅从从节点读取
// - secondaryPreferred:从节点如果可用,否则主节点
// - nearest:最低网络延迟
db.collection.find().readPref("secondaryPreferred")
D. 事务
多文档ACID事务:
const session = client.startSession();
session.startTransaction();
try {
await accounts.updateOne(
{ _id: fromAccount },
{ $inc: { balance: -amount } },
{ session }
);
await accounts.updateOne(
{ _id: toAccount },
{ $inc: { balance: amount } },
{ session }
);
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
throw error;
} finally {
session.endSession();
}
V. 分片和水平扩展
A. 分片集群架构
组件:
- 分片: 保存数据子集的副本集
- 配置服务器: 存储集群元数据
- Mongos: 查询路由器,将操作定向到分片
B. 分片键选择
关键: 分片键决定数据分布和查询性能。
好的分片键:
- 高基数(许多唯一值)
- 均匀分布(无热点)
- 与查询对齐(查询包括分片键)
// 在数据库上启用分片
sh.enableSharding("myDatabase")
// 用哈希键分片集合
sh.shardCollection(
"myDatabase.users",
{ userId: "hashed" }
)
// 用复合键分片
sh.shardCollection(
"myDatabase.orders",
{ customerId: 1, orderDate: 1 }
)
C. 区域分片
将数据范围分配给特定分片:
// 添加分片标签
sh.addShardTag("shard0", "US-EAST")
sh.addShardTag("shard1", "US-WEST")
// 将范围分配给区域
sh.addTagRange(
"myDatabase.users",
{ zipcode: "00000" },
{ zipcode: "50000" },
"US-EAST"
)
D. 查询路由
// 目标查询(包括分片键) - 快速
db.users.find({ userId: "12345" })
// 分散收集(无分片键) - 慢速
db.users.find({ email: "user@example.com" })
VI. 安全
A. 认证
方法:
- SCRAM(用户名/密码) - 默认
- X.509证书 - 相互TLS
- LDAP(企业版)
- Kerberos(企业版)
- AWS IAM
- OIDC(OpenID Connect)
// 创建管理员用户
use admin
db.createUser({
user: "admin",
pwd: "strongPassword",
roles: ["root"]
})
// 创建数据库用户
use myDatabase
db.createUser({
user: "appUser",
pwd: "password",
roles: [
{ role: "readWrite", db: "myDatabase" }
]
})
B. 基于角色的访问控制(RBAC)
内置角色:
read,readWrite:集合级别dbAdmin,dbOwner:数据库管理userAdmin:用户管理clusterAdmin:集群管理root:超级用户
自定义角色:
db.createRole({
role: "customRole",
privileges: [
{
resource: { db: "myDatabase", collection: "users" },
actions: ["find", "update"]
}
],
roles: []
})
C. 加密
静态加密
// 在mongod.conf中配置
security:
enableEncryption: true
encryptionKeyFile: /path/to/keyfile
传输加密(TLS/SSL)
// mongod.conf
net:
tls:
mode: requireTLS
certificateKeyFile: /path/to/cert.pem
CAFile: /path/to/ca.pem
客户端字段级加密(CSFLE)
// 敏感字段的自动加密
const clientEncryption = new ClientEncryption(client, {
keyVaultNamespace: "encryption.__keyVault",
kmsProviders: {
aws: {
accessKeyId: "...",
secretAccessKey: "..."
}
}
})
// 创建数据键
const dataKeyId = await clientEncryption.createDataKey("aws", {
masterKey: { region: "us-east-1", key: "..." }
})
// 配置自动加密
const encryptedClient = new MongoClient(uri, {
autoEncryption: {
keyVaultNamespace: "encryption.__keyVault",
kmsProviders: { aws: {...} },
schemaMap: {
"myDatabase.users": {
bsonType: "object",
properties: {
ssn: {
encrypt: {
keyId: [dataKeyId],
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
}
}
}
}
})
VII. 部署选项
A. MongoDB Atlas(云)
推荐大多数用例。
快速入门:
- 在mongodb.com/atlas创建免费M0集群
- 白名单IP地址
- 创建数据库用户
- 获取连接字符串
功能:
- 自动扩展
- 自动备份
- 多云(AWS、Azure、GCP)
- 多区域部署
- Atlas搜索和向量搜索
- 图表(嵌入式分析)
- 数据联邦
- 无服务器实例
连接:
const uri = "mongodb+srv://user:pass@cluster.mongodb.net/database?retryWrites=true&w=majority";
const client = new MongoClient(uri);
B. 自管理
安装:
# Ubuntu/Debian
wget -qO - https://www.mongodb.org/static/pgp/server-8.0.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
sudo apt-get update
sudo apt-get install -y mongodb-org
# 启动
sudo systemctl start mongod
sudo systemctl enable mongod
配置(mongod.conf):
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
net:
port: 27017
bindIp: 127.0.0.1
security:
authorization: enabled
replication:
replSetName: "myReplicaSet"
C. Kubernetes部署
MongoDB Kubernetes操作符:
apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
name: mongodb-replica-set
spec:
members: 3
type: ReplicaSet
version: "8.0"
security:
authentication:
modes: ["SCRAM"]
users:
- name: admin
db: admin
passwordSecretRef:
name: mongodb-admin-password
roles:
- name: root
db: admin
statefulSet:
spec:
volumeClaimTemplates:
- metadata:
name: data-volume
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
VIII. 集成和驱动程序
A. 官方驱动程序(15+语言)
Node.js
const { MongoClient } = require("mongodb");
const client = new MongoClient(uri);
await client.connect();
const db = client.db("myDatabase");
const collection = db.collection("users");
// CRUD
await collection.insertOne({ name: "Alice" });
const user = await collection.findOne({ name: "Alice" });
await collection.updateOne({ name: "Alice" }, { $set: { age: 30 } });
await collection.deleteOne({ name: "Alice" });
Python(PyMongo)
from pymongo import MongoClient
client = MongoClient(uri)
db = client.myDatabase
collection = db.users
# CRUD
collection.insert_one({"name": "Alice"})
user = collection.find_one({"name": "Alice"})
collection.update_one({"name": "Alice"}, {"$set": {"age": 30}})
collection.delete_one({"name": "Alice"})
Java
MongoClient mongoClient = MongoClients.create(uri);
MongoDatabase database = mongoClient.getDatabase("myDatabase");
MongoCollection<Document> collection = database.getCollection("users");
// 插入
collection.insertOne(new Document("name", "Alice"));
// 查找
Document user = collection.find(eq("name", "Alice")).first();
// 更新
collection.updateOne(eq("name", "Alice"), set("age", 30));
Go
client, _ := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
collection := client.Database("myDatabase").Collection("users")
// 插入
collection.InsertOne(context.TODO(), bson.M{"name": "Alice"})
// 查找
var user bson.M
collection.FindOne(context.TODO(), bson.M{"name": "Alice"}).Decode(&user)
B. 集成工具
Kafka连接器
{
"connector.class": "com.mongodb.kafka.connect.MongoSinkConnector",
"connection.uri": "mongodb://localhost:27017",
"database": "myDatabase",
"collection": "events",
"topics": "my-topic"
}
Spark连接器
val df = spark.read
.format("mongodb")
.option("uri", "mongodb://localhost:27017/myDatabase.myCollection")
.load()
df.filter($"age" > 18).show()
BI连接器(SQL接口)
-- 使用SQL查询MongoDB
SELECT name, AVG(age) as avg_age
FROM users
WHERE status = 'active'
GROUP BY name;
IX. 高级功能
A. Atlas搜索(全文)
创建搜索索引:
{
"mappings": {
"dynamic": false,
"fields": {
"title": {
"type": "string",
"analyzer": "lucene.standard"
},
"description": {
"type": "string",
"analyzer": "lucene.english"
}
}
}
}
查询:
db.articles.aggregate([
{
$search: {
text: {
query: "mongodb database",
path: ["title", "description"],
fuzzy: { maxEdits: 1 }
}
}
},
{ $limit: 10 },
{ $project: { title: 1, description: 1, score: { $meta: "searchScore" } } }
])
B. Atlas向量搜索
用于AI/ML相似性搜索:
db.products.aggregate([
{
$vectorSearch: {
index: "vector_index",
path: "embedding",
queryVector: [0.123, 0.456, ...], // OpenAI的1536维度
numCandidates: 100,
limit: 10
}
},
{
$project: {
name: 1,
description: 1,
score: { $meta: "vectorSearchScore" }
}
}
])
C. 变更流(实时)
const changeStream = collection.watch([
{ $match: { "fullDocument.status": "active" } }
]);
changeStream.on("change", (change) => {
console.log("检测到变更:", change);
// change.operationType: "insert", "update", "delete", "replace"
// change.fullDocument: 完整文档(如果配置)
});
// 从特定点恢复
const resumeToken = changeStream.resumeToken;
const newStream = collection.watch([], { resumeAfter: resumeToken });
D. 批量操作
const bulkOps = [
{ insertOne: { document: { name: "Alice", age: 30 } } },
{ updateOne: {
filter: { name: "Bob" },
update: { $set: { age: 25 } },
upsert: true
}},
{ deleteOne: { filter: { name: "Charlie" } } }
];
const result = await collection.bulkWrite(bulkOps, { ordered: false });
console.log(`插入:${result.insertedCount}, 更新:${result.modifiedCount}`);
X. 性能优化
最佳实践
-
索引关键字段
- 索引用于查询、排序、连接的字段
- 监控慢查询(>100ms)
- 为多字段查询使用复合索引
-
使用投影
// 好:仅返回所需字段 db.users.find({ status: "active" }, { name: 1, email: 1 }) // 坏:返回整个文档 db.users.find({ status: "active" }) -
限制结果集
db.users.find().limit(100) -
使用聚合管道
- 在服务器端处理数据,而不是客户端
- 早期使用
$match过滤 - 使用
$project减少文档大小
-
连接池
const client = new MongoClient(uri, { maxPoolSize: 50, minPoolSize: 10 }); -
批量写入
// 好:批量插入 await collection.insertMany(documents); // 坏:单独插入 for (const doc of documents) { await collection.insertOne(doc); } -
写入关注调优
- 使用
w: 1用于非关键写入(更快) - 使用
w: "majority"用于关键数据(更安全)
- 使用
-
读取偏好
- 使用
secondary用于读取密集型分析 - 使用
primary用于强一致性
- 使用
监控
// 检查慢查询
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(10)
// 当前操作
db.currentOp()
// 服务器状态
db.serverStatus()
// 集合统计
db.collection.stats()
XI. 故障排除
常见错误
| 错误 | 原因 | 解决方案 |
|---|---|---|
MongoNetworkError |
连接失败 | 检查网络、IP白名单、凭据 |
E11000 duplicate key |
重复唯一字段 | 检查唯一索引,处理重复 |
ValidationError |
模式验证失败 | 检查文档结构、字段类型 |
OperationTimeout |
查询太慢 | 添加索引、优化查询、增加超时 |
AggregationResultTooLarge |
结果 > 16MB | 使用 $limit、$project 或 $out |
InvalidSharKey |
坏的分片键 | 选择高基数、均匀分布的键 |
ChunkTooBig |
巨块 | 使用 refineShardKey 或重新分片 |
OplogTailFailed |
复制延迟 | 检查网络,增加操作日志大小 |
调试工具
// 解释查询计划
db.collection.find({ field: value }).explain("executionStats")
// 检查索引使用
db.collection.aggregate([{ $indexStats: {} }])
// 分析慢查询
db.setProfilingLevel(2) // 分析所有查询
db.system.profile.find({ millis: { $gt: 100 } })
// 检查复制延迟
rs.printReplicationInfo()
rs.printSecondaryReplicationInfo()
XII. 快速参考
前20个操作(按频率)
find()- 查询文档updateOne()/updateMany()- 修改文档insertOne()/insertMany()- 添加文档deleteOne()/deleteMany()- 移除文档aggregate()- 复杂查询createIndex()- 性能优化explain()- 查询分析findOne()- 获取单个文档countDocuments()- 计数匹配replaceOne()- 替换文档distinct()- 获取唯一值bulkWrite()- 批量操作findAndModify()- 原子更新watch()- 监控变更sort()/limit()/skip()- 结果操作$lookup- 连接集合$group- 聚合数据$match- 过滤管道$project- 塑造输出hint()- 强制索引
常见模式
分页:
const page = 2;
const pageSize = 20;
db.collection.find()
.skip((page - 1) * pageSize)
.limit(pageSize)
基于游标的分页(更好):
const lastId = ObjectId("...");
db.collection.find({ _id: { $gt: lastId } })
.limit(20)
原子计数器:
db.counters.findAndModify({
query: { _id: "sequence" },
update: { $inc: { value: 1 } },
new: true,
upsert: true
})
软删除:
// 标记为已删除
db.users.updateOne({ _id: userId }, { $set: { deleted: true, deletedAt: new Date() } })
// 仅查询活跃
ndb.users.find({ deleted: { $ne: true } })
XIII. 资源
官方文档
- 完整文档: https://www.mongodb.com/docs/
- MongoDB手册: https://www.mongodb.com/docs/manual/
- 驱动程序: https://www.mongodb.com/docs/drivers/
- Atlas: https://www.mongodb.com/docs/atlas/
工具
- MongoDB Compass - MongoDB的GUI
- MongoDB Shell (mongosh) - 现代shell
- Atlas CLI - 自动化Atlas操作
- 数据库工具 - mongodump、mongorestore、mongoimport
最佳实践摘要
- 始终使用索引 用于查询字段
- 嵌入 vs. 引用: 嵌入用于一对少,引用用于一对多
- 分片键: 高基数 + 均匀分布 + 与查询对齐
- 安全: 启用认证,使用TLS,为生产加密静态数据
- 复制: 至少3个节点用于高可用性
- 写入关注:
w: "majority"用于关键数据 - 监控: 跟踪慢查询、复制延迟、磁盘使用
- 测试: 使用explain()验证查询性能
- 连接池: 配置适当的池大小
- 模式验证: 定义模式以确保数据完整性
XIV. 版本特定功能
MongoDB 8.0(当前)
- 配置分片(结合配置和分片角色)
- 改进的聚合性能
- 增强的安全功能
MongoDB 7.0
- 自动合并块
- 时间序列改进
- 可查询加密GA
MongoDB 6.0
- 重新分片支持
- 集群集合
- 时间序列集合改进
MongoDB 5.0
- 时间序列集合
- 实时重新分片
- 版本化API
常见用例
电子商务
- 产品目录(嵌入属性)
- 订单(用于一致性的事务)
- 用户会话(TTL索引用于清理)
- 搜索(Atlas搜索用于产品)
IoT/时间序列
- 传感器数据(时间序列集合)
- 实时分析(变更流)
- 保留策略(TTL索引)
社交网络
- 用户档案(嵌入或引用)
- 帖子和评论(小规模嵌入,大规模引用)
- 实时订阅源(变更流)
- 搜索(Atlas搜索用于内容)
分析
- 事件跟踪(高写入吞吐量)
- 聚合管道(复杂分析)
- 数据联邦(跨源查询)
何时不使用MongoDB
- 强调一致性而非可用性(使用传统RDBMS)
- 复杂的多表连接(SQL数据库在此表现更好)
- 极小的数据集(<1GB)且简单查询
- 跨多个数据库的ACID事务(不支持)
此技能提供全面的MongoDB知识,用于实施数据库解决方案,从基本CRUD操作到高级分布式系统,包括分片、复制和安全。始终参考官方文档以获取最新功能和版本特定细节。