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")
关注期望
stageIXSCAN 而非 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。