🍃 MongoDB 速查手册

1. 连接与基础命令

🔌 连接数据库

功能命令
本地连接mongoshmongo
远程连接(参数方式)mongosh --host <host> --port <port> -u <user> -p <password> --authenticationDatabase admin
连接字符串方式mongosh "mongodb://username:password@host:port/database?authSource=admin"
连接副本集mongosh "mongodb://host1:port1,host2:port2/database?replicaSet=rsName"

📁 数据库操作

命令说明
show dbs / show databases显示所有数据库
use <database_name>切换/创建数据库
db显示当前数据库
db.dropDatabase()🗑️ 删除当前数据库
db.stats()显示数据库统计信息

📊 集合操作

命令说明
show collections / show tables显示所有集合
db.createCollection("name", options)创建集合
db.collection.drop()🗑️ 删除集合
db.collection.stats()集合统计信息

2. 📝 CRUD 操作

➕ 插入文档

// 插入单条文档
db.users.insertOne({
    name: "张三",
    age: 25,
    email: "zhangsan@example.com",
    created_at: new Date()
})

// 插入多条文档(有序)
db.users.insertMany([
    {name: "李四", age: 30},
    {name: "王五", age: 28}
])

// 插入多条文档(无序,出错继续)
db.users.insertMany([...], { ordered: false })

🔍 查询文档

// 基础查询
db.users.find()                    // 查询所有
db.users.find().pretty()           // 美化输出
db.users.findOne({age: 25})        // 查询单条

// 条件查询
db.users.find({age: {$gt: 25}})                    // 年龄大于25
db.users.find({age: {$gte: 20, $lte: 30}})         // 年龄20-30之间
db.users.find({name: {$in: ["张三", "李四"]}})      // 名字在列表中
db.users.find({name: /^张/})                       // 正则匹配:姓张

// 投影(指定返回字段)
db.users.find({}, {name: 1, email: 1})             // 只返回name和email
db.users.find({}, {password: 0})                   // 排除password字段

// 排序、限制、跳过
db.users.find().sort({age: -1})                    // 按年龄降序
db.users.find().limit(10)                          // 限制10条
db.users.find().skip(20).limit(10)                 // 分页:第3页

✏️ 更新文档

// 更新操作符
db.users.updateOne(
    {name: "张三"},
    {
        $set: {age: 26, updated_at: new Date()},           // 设置字段
        $inc: {login_count: 1},                            // 字段自增
        $unset: {temp_field: ""},                          // 删除字段
        $push: {hobbies: "篮球"},                          // 数组添加元素
        $addToSet: {tags: "VIP"}                           // 数组添加不重复元素
    }
)

// 更新多条
db.users.updateMany(
    {status: "active"},
    {$set: {last_active: new Date()}}
)

// 替换文档
db.users.replaceOne(
    {name: "张三"},
    {name: "张三", age: 26, city: "北京"}  // 完全替换,注意会覆盖其他字段
)

// Upsert(不存在则插入)
db.users.updateOne(
    {email: "new@example.com"},
    {$set: {name: "新人", created_at: new Date()}},
    {upsert: true}
)

🗑️ 删除文档

db.users.deleteOne({name: "张三"})           // 删除单条
db.users.deleteMany({status: "inactive"})    // 删除多条
db.users.findOneAndDelete({age: {$lt: 18}})  // 查找并删除,返回被删除文档

3. 🎯 高级查询技巧

🔎 查询操作符

类型操作符示例说明
比较$eq, $ne{age: {$eq: 25}}等于、不等于
$gt, $gte{age: {$gt: 18}}大于、大于等于
$lt, $lte{age: {$lt: 65}}小于、小于等于
$in, $nin{role: {$in: ["admin", "user"]}}在/不在列表中
逻辑$and{$and: [{age: {$gt: 18}}, {age: {$lt: 30}}]}与条件
$or{$or: [{status: "active"}, {vip: true}]}或条件
$not{age: {$not: {$lt: 18}}}非条件
$nor{$nor: [{price: 1.99}, {sale: true}]}或非条件
元素$exists{email: {$exists: true}}字段存在
$type{age: {$type: "number"}}字段类型
数组$all{tags: {$all: ["mongodb", "database"]}}包含所有元素
$elemMatch{results: {$elemMatch: {$gte: 80, $lt: 90}}}数组元素匹配
$size{tags: {$size: 3}}数组大小

📊 聚合管道

// 复杂数据分析
db.orders.aggregate([
    // 阶段1:筛选条件
    { $match: { 
        status: "completed",
        order_date: { $gte: ISODate("2024-01-01") }
    }},
    
    // 阶段2:关联查询
    { $lookup: {
        from: "users",
        localField: "user_id",
        foreignField: "_id",
        as: "user_info"
    }},
    
    // 阶段3:展开数组
    { $unwind: "$items" },
    
    // 阶段4:分组统计
    { $group: {
        _id: "$user_id",
        total_amount: { $sum: "$items.price" },
        order_count: { $sum: 1 },
        avg_order_value: { $avg: "$total" },
        first_order: { $min: "$order_date" },
        last_order: { $max: "$order_date" }
    }},
    
    // 阶段5:字段投影
    { $project: {
        user_id: "$_id",
        total_amount: 1,
        order_count: 1,
        avg_order_value: { $round: ["$avg_order_value", 2] },
        customer_since: "$first_order"
    }},
    
    // 阶段6:结果排序
    { $sort: { total_amount: -1 } },
    
    // 阶段7:输出限制
    { $limit: 10 }
])

🔤 文本搜索

// 创建文本索引
db.articles.createIndex({ title: "text", content: "text" })

// 文本搜索
db.articles.find({ 
    $text: { 
        $search: "mongodb tutorial",
        $caseSensitive: false,
        $diacriticSensitive: false
    }
})

// 按文本搜索评分排序
db.articles.find(
    { $text: { $search: "database" } },
    { score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } })

4. ⚡ 索引优化

📑 索引管理

// 查看索引
db.collection.getIndexes()

// 创建索引
db.users.createIndex({ email: 1 }, { unique: true })           // 唯一索引
db.users.createIndex({ created_at: 1 }, { expireAfterSeconds: 3600 }) // TTL索引
db.products.createIndex({ name: "text", description: "text" }) // 文本索引
db.users.createIndex({ location: "2dsphere" })                 // 地理空间索引
db.users.createIndex({ age: 1, city: 1 })                      // 复合索引

// 删除索引
db.users.dropIndex("email_1")              // 删除指定索引
db.users.dropIndexes()                     // 删除所有索引

📈 查询分析

// 查询分析
db.users.find({age: {$gt: 25}}).explain("executionStats")  // 详细执行计划
db.users.find({email: "test@example.com"}).hint({email: 1}) // 强制使用索引

5. 🔐 用户与权限管理

👥 用户管理

// 创建用户
db.createUser({
    user: "admin",
    pwd: "password123",
    roles: [
        { role: "root", db: "admin" },           // 超级管理员
        { role: "readWrite", db: "mydb" }        // 数据库读写权限
    ]
})

// 常用角色
// - read: 只读权限
// - readWrite: 读写权限  
// - dbAdmin: 数据库管理
// - userAdmin: 用户管理
// - clusterAdmin: 集群管理
// - root: 超级权限

// 用户管理命令
db.dropUser("username")                         // 删除用户
db.updateUser("username", {roles: [...]})       // 更新用户
db.changeUserPassword("username", "newpass")    // 修改密码
db.grantRolesToUser("username", [{role: "read", db: "dbname"}])
db.revokeRolesFromUser("username", [{role: "read", db: "dbname"}])

6. 🏗️ 数据模型设计

🔄 引用式 vs 嵌入式

// 嵌入式文档(一对少,数据不经常变化)
{
    _id: 1,
    name: "用户订单",
    orders: [
        { product: "手机", price: 2999, date: ISODate("2024-01-01") },
        { product: "耳机", price: 399, date: ISODate("2024-01-02") }
    ]
}

// 引用式文档(一对多,数据频繁变化)
// users集合
{
    _id: ObjectId("..."),
    name: "张三",
    email: "zhangsan@example.com"
}

// orders集合  
{
    _id: ObjectId("..."),
    user_id: ObjectId("..."),  // 引用用户ID
    products: [...],
    total: 3398
}

7. 🛠️ 实用工具函数

📋 批量操作

// 批量写入
const bulkOps = [
    { insertOne: { document: { name: "User1" } } },
    { updateOne: { filter: { name: "User2" }, update: { $set: { status: "active" } } } },
    { deleteOne: { filter: { name: "User3" } } }
]

db.users.bulkWrite(bulkOps, { ordered: false })

🔄 数据导入导出

# 导出数据
mongodump --uri="mongodb://localhost:27017/mydb" --out=/backup/path

# 导入数据  
mongorestore --uri="mongodb://localhost:27017/mydb" /backup/path/mydb

# 导出为JSON
mongoexport --uri="mongodb://localhost:27017/mydb" --collection=users --out=users.json

# 从JSON导入
mongoimport --uri="mongodb://localhost:27017/mydb" --collection=users --file=users.json

8. 📚 最佳实践

✅ 设计原则

  1. 适当地使用索引 - 在查询字段上创建索引,但避免过度索引
  2. 使用投影 - 只返回需要的字段,减少网络传输
  3. 合理分页 - 使用 skip() + limit() 或基于游标的分页
  4. 避免大文档 - 单个文档建议不超过16MB
  5. 使用合适的 - 根据业务场景选择嵌入式或引用式文档

❌ 常见陷阱

// 避免:不使用索引的查询
db.users.find({$where: "this.age > 25"})  // 全表扫描

// 推荐:使用索引的查询  
db.users.find({age: {$gt: 25}}).hint({age: 1})

// 避免:返回过大结果集
db.users.find()  // 可能返回数百万文档

// 推荐:使用限制和投影
db.users.find({}, {name: 1}).limit(1000)

添加新评论