#MongoDB 速查
#mongosh 基础
show dbs
use demo
show collections
db.users.find().pretty()
db.users.stats()
db.users.countDocuments({ status: "active" })
db.users.drop()#查询操作符
| 类别 | 操作符 |
|---|---|
| 比较 | $eq $ne $gt $gte $lt $lte $in $nin |
| 逻辑 | $and $or $not $nor |
| 元素 | $exists $type |
| 数组 | $all $elemMatch $size |
| 正则 | $regex |
db.users.find({ "address.city": "北京" })
db.orders.find({ status: { $in: ["paid", "shipped"] } })
db.orders.find({ amount: { $gte: 100 }, $or: [{ vip: true }, { level: "A" }] })
db.orders.find({ items: { $elemMatch: { qty: { $gt: 5 } } } })
db.articles.find({ tags: { $all: ["go", "db"] } })
db.orders.find({ status: "paid" }, { amount: 1, createdAt: 1, _id: 0 })
.sort({ createdAt: -1 }).skip(0).limit(20)#更新操作符
| 操作符 | 作用 |
|---|---|
$set / $unset | 设置 / 删除字段 |
$inc | 数值自增(原子) |
$push / $pull / $addToSet | 数组增 / 删 / 去重增 |
$rename | 重命名字段 |
$mul / $min / $max | 数值运算 |
db.inventory.updateOne(
{ sku: "A001" },
{ $inc: { qty: -1 }, $set: { updatedAt: new Date() } },
{ upsert: true }
)
db.users.updateOne({ _id: 1 }, { $addToSet: { tags: "vip" } })
db.orders.updateMany({ status: "pending" }, { $set: { status: "expired" } })
db.counters.findOneAndUpdate(
{ _id: "order_id" }, { $inc: { seq: 1 } },
{ upsert: true, returnDocument: "after" }
)#删除
db.orders.deleteOne({ _id: 1 })
db.orders.deleteMany({ status: "expired" })
db.orders.findOneAndDelete({ _id: 2 })#聚合阶段
| 阶段 | 作用 |
|---|---|
$match | 过滤(放最前) |
$project | 选择/计算字段 |
$group | 分组聚合($sum/$avg/$push) |
$sort | 排序 |
$limit / $skip | 分页 |
$unwind | 展开数组 |
$lookup | 左外连接 |
$facet | 多路聚合 |
$out / $merge | 结果落库 |
db.orders.aggregate([
{ $match: { status: "paid" } },
{ $group: { _id: "$user_id", gmv: { $sum: "$amount" }, orders: { $sum: 1 } } },
{ $sort: { gmv: -1 } },
{ $limit: 10 },
{ $lookup: { from: "users", localField: "_id", foreignField: "_id", as: "user" } },
{ $unwind: "$user" },
{ $project: { _id: 0, user: "$user.name", gmv: 1 } }
])#索引
db.users.createIndex({ email: 1 }, { unique: true })
db.orders.createIndex({ userId: 1, createdAt: -1 }) // ESR
db.orders.createIndex({ status: 1 }, { partialFilterExpression: { status: "paid" } })
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 }) // TTL
db.products.createIndex({ name: "text", description: "text" })
db.orders.getIndexes()
db.orders.dropIndex("userId_1_createdAt_-1")
db.orders.aggregate([{ $indexStats: {} }]) // 索引使用统计
db.orders.find({...}).explain("executionStats")| 关注 | 期望 |
|---|---|
stage | IXSCAN 而非 COLLSCAN |
totalDocsExamined | 接近 nReturned;覆盖查询为 0 |
SORT 阶段 | 不应出现(否则未用索引排序) |
#副本集与分片
rs.status()
rs.stepDown()
db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })
db.adminCommand({ setFeatureCompatibilityVersion: "7.0" })
sh.enableSharding("demo")
sh.shardCollection("demo.orders", { userId: "hashed" })
sh.status()#多文档事务
const session = db.getMongo().startSession()
session.startTransaction({ readConcern: { level: "snapshot" },
writeConcern: { w: "majority" } })
try {
session.getDatabase("demo").accounts.updateOne({ _id: 1 }, { $inc: { balance: -100 } }, { session })
session.getDatabase("demo").accounts.updateOne({ _id: 2 }, { $inc: { balance: 100 } }, { session })
session.commitTransaction()
} catch (e) { session.abortTransaction(); throw e } finally { session.endSession() }#小结
- 查询操作用点号访问嵌套字段;数组用
$elemMatch/$all。 - 更新优先原子操作符(
$inc/$push/$addToSet)配upsert。 - 聚合
$match/$sort前置;复合索引遵循 ESR。 - 写关注
majority、逐版本升级 + FCV。