Skip to content

集合操作

集合(Collection)是MongoDB中存储文档的容器,类似于关系数据库中的表。本章将介绍集合的创建、管理和删除等操作。

集合概念

什么是集合

javascript
// 集合是MongoDB中存储文档的容器

// 集合的特点:
// 1. 集合中的文档可以有不同的结构(灵活Schema)
// 2. 集合不需要预先定义字段
// 3. 集合位于数据库中
// 4. 集合名称区分大小写

// 集合与关系数据库表的对比:
// +------------------+------------------+
// | MongoDB集合      | 关系数据库表     |
// +------------------+------------------+
// | 文档(Document) | 行(Row)        |
// | 字段(Field)    | 列(Column)     |
// | 灵活Schema       | 固定Schema       |
// | 嵌套文档         | 需要多表关联      |
// +------------------+------------------+

集合命名规则

javascript
// 集合命名规则:

// 1. 名称限制
//    - 不能是空字符串
//    - 不能包含$符号
//    - 不能以system.开头(系统集合前缀)
//    - 不能包含\0(空字符)

// 2. 推荐命名方式
//    - 使用小写字母
//    - 使用下划线或驼峰命名
//    - 名称要有意义
//    - 复数形式表示多个文档

// 推荐的集合名称示例
db.users           // 用户集合
db.products        // 产品集合
db.order_items     // 订单项集合
db.userProfiles    // 用户档案集合

// 不推荐的集合名称示例
// db.User           // 不推荐大写
// db.user-info      // 不推荐连字符
// db.$users         // 不能包含$
// db.system.users   // 不能以system.开头

创建集合

显式创建集合

javascript
// 使用createCollection方法显式创建集合

// 基本语法
db.createCollection("集合名称")

// 创建users集合
db.createCollection("users")
// 输出:{ ok: 1 }

// 创建带有选项的集合
db.createCollection("logs", {
    capped: true,        // 是否为固定大小集合
    size: 5242880,       // 集合大小(字节),5MB
    max: 5000            // 最大文档数量
})
// 输出:{ ok: 1 }

// 创建带有文档验证的集合
db.createCollection("employees", {
    validator: {
        $jsonSchema: {
            bsonType: "object",
            required: ["name", "age", "department"],  // 必填字段
            properties: {
                name: {
                    bsonType: "string",
                    description: "员工姓名,必填,字符串类型"
                },
                age: {
                    bsonType: "int",
                    minimum: 18,
                    maximum: 65,
                    description: "员工年龄,必填,18-65之间的整数"
                },
                department: {
                    bsonType: "string",
                    description: "所属部门,必填,字符串类型"
                },
                salary: {
                    bsonType: "number",
                    minimum: 0,
                    description: "薪资,可选,非负数"
                }
            }
        }
    },
    validationLevel: "strict",     // 验证级别
    validationAction: "error"      // 验证失败时的行为
})
// 输出:{ ok: 1 }

隐式创建集合

javascript
// MongoDB支持隐式创建集合
// 当向不存在的集合插入文档时,会自动创建该集合

// 向不存在的集合插入文档
db.products.insertOne({
    name: "MacBook Pro",
    price: 12999,
    category: "电脑"
})
// 输出:
// {
//   acknowledged: true,
//   insertedId: ObjectId("...")
// }

// 集合products已自动创建
show collections
// 输出:
// products

固定大小集合(Capped Collection)

javascript
// 固定大小集合的特点:
// 1. 固定大小,超出时自动删除最旧的文档
// 2. 插入顺序保证
// 3. 不允许删除文档(只能整体删除集合)
// 4. 更新操作不能增加文档大小
// 5. 适合日志、缓存等场景

// 创建固定大小集合
db.createCollection("system_logs", {
    capped: true,
    size: 10485760,    // 10MB大小限制
    max: 10000         // 最多10000条文档
})

// 插入日志数据
db.system_logs.insertOne({
    level: "INFO",
    message: "系统启动",
    timestamp: new Date()
})

// 查看集合是否为固定大小
db.system_logs.isCapped()
// 输出:true

// 将普通集合转换为固定大小集合
db.runCommand({
    convertToCapped: "logs",
    size: 5242880
})

查看集合

查看所有集合

javascript
// 查看当前数据库的所有集合
show collections
// 或
db.getCollectionNames()

// 输出示例:
// [ 'employees', 'products', 'system_logs', 'users' ]

查看集合详情

javascript
// 查看集合统计信息
db.users.stats()

// 输出示例:
// {
//   ns: 'mydb.users',           // 命名空间
//   count: 1000,                // 文档数量
//   size: 111000,               // 数据大小(字节)
//   avgObjSize: 111,            // 平均文档大小
//   storageSize: 36864,         // 存储大小
//   nindexes: 1,                // 索引数量
//   totalIndexSize: 36864,      // 索引总大小
//   ...
// }

// 查看简化的集合信息
db.users.stats({ scale: 1024 })  // 以KB为单位
db.users.stats({ scale: 1024 * 1024 })  // 以MB为单位

// 查看集合的数据大小
db.users.dataSize()      // 数据大小
db.users.storageSize()   // 存储大小
db.users.totalIndexSize() // 索引大小
db.users.totalSize()     // 总大小

查看集合选项

javascript
// 查看集合的创建选项
db.getCollectionInfos({ name: "system_logs" })

// 输出示例:
// [
//   {
//     name: 'system_logs',
//     type: 'collection',
//     options: {
//       capped: true,
//       size: 10485760,
//       max: 10000
//     },
//     info: {
//       readOnly: false,
//       uuid: UUID("...")
//     },
//     idIndex: { ... }
//   }
// ]

修改集合

重命名集合

javascript
// 重命名集合
db.users.renameCollection("members")

// 输出:{ ok: 1 }

// 跨数据库重命名(需要使用admin命令)
db.adminCommand({
    renameCollection: "mydb.users",
    to: "mydb.members"
})

// 重命名并保留原集合(复制)
db.users.aggregate([
    { $out: "members" }
])

修改集合验证规则

javascript
// 添加文档验证规则
db.runCommand({
    collMod: "products",
    validator: {
        $jsonSchema: {
            bsonType: "object",
            required: ["name", "price"],
            properties: {
                name: {
                    bsonType: "string",
                    minLength: 1,
                    description: "产品名称,必填"
                },
                price: {
                    bsonType: "number",
                    minimum: 0,
                    description: "价格,必填,非负数"
                },
                stock: {
                    bsonType: "int",
                    minimum: 0,
                    description: "库存,非负整数"
                }
            }
        }
    },
    validationLevel: "moderate",  // 只验证更新的文档
    validationAction: "warn"      // 验证失败时警告而非报错
})

// 移除验证规则
db.runCommand({
    collMod: "products",
    validator: {}
})

修改集合选项

javascript
// 修改固定大小集合的大小
db.runCommand({
    collMod: "system_logs",
    cappedSize: 20971520  // 新大小:20MB
})

// 修改最大文档数
db.runCommand({
    collMod: "system_logs",
    cappedMax: 20000  // 新最大文档数
})

// 启用/禁用文档标志位
db.runCommand({
    collMod: "products",
    recordPreImages: true  // 启用变更流的前镜像
})

删除集合

删除单个集合

javascript
// 删除集合
db.users.drop()

// 输出:true(删除成功)

// 删除不存在的集合
db.nonexistent.drop()
// 输出:false(集合不存在)

// 删除集合会同时删除:
// 1. 所有文档
// 2. 所有索引
// 3. 集合的元数据

批量删除集合

javascript
// 批量删除集合(编写脚本)

// 获取所有集合名称
var collections = db.getCollectionNames()

// 删除以"temp_"开头的集合
collections.forEach(function(collectionName) {
    if (collectionName.startsWith("temp_")) {
        db.getCollection(collectionName).drop()
        print("已删除集合: " + collectionName)
    }
})

// 删除所有集合(危险操作,谨慎使用)
db.getCollectionNames().forEach(function(collectionName) {
    if (!collectionName.startsWith("system.")) {
        db.getCollection(collectionName).drop()
        print("已删除集合: " + collectionName)
    }
})

文档验证

JSON Schema验证

javascript
// 使用JSON Schema进行文档验证

// 创建带有验证的集合
db.createCollection("orders", {
    validator: {
        $jsonSchema: {
            bsonType: "object",
            required: ["orderId", "userId", "items", "totalAmount"],
            properties: {
                orderId: {
                    bsonType: "string",
                    pattern: "^ORD[0-9]{8}$",
                    description: "订单ID,格式:ORD+8位数字"
                },
                userId: {
                    bsonType: "objectId",
                    description: "用户ID,ObjectId类型"
                },
                items: {
                    bsonType: "array",
                    minItems: 1,
                    items: {
                        bsonType: "object",
                        required: ["productId", "quantity", "price"],
                        properties: {
                            productId: { bsonType: "objectId" },
                            quantity: { bsonType: "int", minimum: 1 },
                            price: { bsonType: "number", minimum: 0 }
                        }
                    },
                    description: "订单项数组,至少一项"
                },
                totalAmount: {
                    bsonType: "number",
                    minimum: 0,
                    description: "订单总金额"
                },
                status: {
                    enum: ["pending", "paid", "shipped", "completed", "cancelled"],
                    description: "订单状态"
                },
                createdAt: {
                    bsonType: "date",
                    description: "创建时间"
                }
            }
        }
    }
})

// 测试验证
// 有效文档
db.orders.insertOne({
    orderId: "ORD20240101",
    userId: ObjectId(),
    items: [
        { productId: ObjectId(), quantity: NumberInt(2), price: 99.99 }
    ],
    totalAmount: 199.98,
    status: "pending",
    createdAt: new Date()
})
// 插入成功

// 无效文档(缺少必填字段)
db.orders.insertOne({
    orderId: "ORD20240102"
})
// 报错:Document failed validation

查询表达式验证

javascript
// 使用查询表达式进行验证

db.createCollection("inventory", {
    validator: {
        $and: [
            { quantity: { $gte: 0 } },           // 数量非负
            { price: { $gt: 0 } },               // 价格必须大于0
            { category: { $in: ["电子", "服装", "食品", "家居"] } }  // 分类限制
        ]
    }
})

// 验证级别
// strict: 对所有插入和更新进行验证(默认)
// moderate: 只对符合验证规则的现有文档的更新进行验证

// 验证行为
// error: 验证失败时拒绝操作(默认)
// warn: 验证失败时允许操作但记录警告

// 设置验证级别和行为
db.runCommand({
    collMod: "inventory",
    validationLevel: "moderate",
    validationAction: "warn"
})

查看验证规则

javascript
// 查看集合的验证规则
db.getCollectionInfos({ name: "orders" })[0].options.validator

// 输出示例:
// {
//   '$jsonSchema': {
//     bsonType: 'object',
//     required: [ 'orderId', 'userId', 'items', 'totalAmount' ],
//     ...
//   }
// }

本章小结

本章介绍了MongoDB集合的基本操作:

  1. 集合概念:理解集合是什么,与关系数据库表的对比
  2. 创建集合:掌握显式创建和隐式创建集合的方法
  3. 固定大小集合:了解Capped Collection的特点和使用场景
  4. 查看集合:学会查看集合列表和详细信息
  5. 修改集合:掌握重命名、修改验证规则等操作
  6. 删除集合:学会删除单个和批量删除集合
  7. 文档验证:掌握使用JSON Schema和查询表达式进行文档验证

下一章,我们将学习文档操作,了解如何对文档进行增删改查操作。