MongoDB核心操作全解析:从安装部署到索引优化实战指南

1. 项目概述:从零到一掌握MongoDB核心操作

如果你正在寻找一个能让你快速上手、灵活处理现代应用数据的数据库,MongoDB绝对是一个绕不开的名字。它早已不是那个只被初创公司用来做原型验证的“玩具”数据库了,如今它支撑着从金融交易到智能推荐、从物联网设备管理到实时分析的各种复杂场景。我接触MongoDB超过十年,从早期的2.x版本一路用到现在的8.x,亲眼看着它从一个文档存储引擎,成长为一个集成了向量搜索、流处理、事务支持的“现代数据平台”。很多人对MongoDB的印象还停留在“存JSON的数据库”,这其实大大低估了它的能力。今天,我就以一个老开发者的视角,带你彻底拆解MongoDB的核心操作,从最基础的安装配置、CRUD(增删改查),到聚合管道、索引优化,再到实际项目中容易踩的坑和性能调优技巧。无论你是刚入门的新手,还是想系统梳理一下知识的中级开发者,这篇文章都能给你带来可以直接落地的实操指南。

2. 环境准备与安装部署:避开那些“启动不了”的坑

在开始任何数据库操作之前,一个稳定、可用的运行环境是基础。根据我多年的经验,安装部署阶段看似简单,却是新手最容易卡住、浪费大量时间的地方,尤其是Windows平台。

2.1 Windows本地安装与故障排查实录

网络上关于“Windows本地安装MongoDB时,提示启动不了”的求助非常多,这几乎是每个Windows开发者入门MongoDB的第一道坎。问题根源通常不在于MongoDB本身,而在于环境配置和权限。

首先,我强烈建议从MongoDB官网下载社区版(Community Edition)的MSI安装包。安装时,最关键的一步是 取消勾选“Install MongoDB Compass” 。Compass是官方GUI工具,虽然好用,但安装过程可能会因为网络或权限问题导致整个安装失败。我们可以先确保数据库服务能跑起来,再单独安装Compass。

安装完成后,服务启动失败,90%的原因出在数据目录和日志目录的权限上。MongoDB默认会尝试在 C:\data\db 创建数据文件,在 C:\data\log 创建日志文件。Windows系统下,普通用户进程通常没有在C盘根目录直接创建文件夹的权限。

我的标准操作流程是:

  1. 手动创建目录:在非系统盘(如D盘)创建目录,例如 D:\mongodb\data\db D:\mongodb\data\log
  2. 通过命令行(以管理员身份运行)启动MongoDB,并显式指定路径:
    mongod --dbpath D:\mongodb\data\db --logpath D:\mongodb\data\log\mongod.log --install --serviceName "MongoDB"
    
    这条命令做了三件事:指定数据路径、指定日志路径、将MongoDB安装为Windows服务。
  3. 启动服务: net start MongoDB

如果还是启动失败,打开 D:\mongodb\data\log\mongod.log 查看日志。最常见的错误是“ Access is denied ”,这说明当前用户对数据目录没有写权限。你需要右键点击 D:\mongodb 文件夹 -> “属性” -> “安全” -> “编辑”,为当前用户或“Users”组添加“完全控制”权限。

另一个高频错误是端口占用。MongoDB默认使用27017端口。如果这个端口被其他程序(如之前未正确关闭的MongoDB实例、某些开发工具)占用,服务也会启动失败。可以用 netstat -ano | findstr :27017 查看端口占用情况,并用任务管理器结束对应进程。

2.2 Linux (Ubuntu) 安装最佳实践

在Ubuntu上安装MongoDB通常更顺畅,但通过包管理器安装的版本可能不是最新的。我习惯使用MongoDB官方提供的仓库来安装。

# 1. 导入MongoDB公共GPG密钥
wget -qO - https://www.mongodb.org/static/pgp/server-8.0.asc | sudo apt-key add -
# 2. 为Ubuntu创建列表文件 (以22.04 Jammy为例)
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
# 3. 更新本地包数据库并安装
sudo apt-get update
sudo apt-get install -y mongodb-org
# 4. 启动服务并设置开机自启
sudo systemctl start mongod
sudo systemctl enable mongod
# 5. 验证服务状态
sudo systemctl status mongod

安装后,MongoDB的配置文件位于 /etc/mongod.conf 。我建议你第一时间修改两个地方:一是将 bindIp 从默认的 127.0.0.1 改为 0.0.0.0 以便远程连接(生产环境务必配合防火墙);二是在 security 部分启用授权 authorization: enabled ,这是安全的第一步。

2.3 权限配置:告别裸奔的数据库

很多新手教程为了省事,会教你禁用认证。这在本地学习可以,但一旦涉及到“Navicat里面怎么配置MongoDB登录需要账号密码的权限”这种问题,就说明你准备连接一个开启了认证的正式环境了。MongoDB的权限体系基于角色(Role)和用户(User)。

首先,你需要一个管理员账号。在未开启认证的情况下,通过 mongo shell连接,执行以下命令:

use admin
db.createUser({
  user: "myAdmin",
  pwd: "aStrongPassword", // 务必使用强密码
  roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
})

这个命令创建了一个能管理所有数据库用户、并能读写所有数据库的管理员。

然后,为你的应用数据库创建专属用户,这是最佳实践:

use myAppDB
db.createUser({
  user: "appUser",
  pwd: "anotherStrongPassword",
  roles: [ { role: "readWrite", db: "myAppDB" } ]
})

这样,你的应用程序就用 appUser 这个专用账号连接 myAppDB ,遵循了最小权限原则。

在Navicat等GUI工具中配置连接时,在“Authentication”选项卡下,选择“SCRAM-SHA-256”方法,然后填入上面创建的用户名、密码和对应的认证数据库( myAppDB )即可。

3. 数据库与集合的基本操作:你的数据容器

MongoDB的逻辑结构是“数据库(Database) -> 集合(Collection) -> 文档(Document)”。它的一大特点是“懒创建”,数据库和集合都不需要预先显式声明,在第一次插入数据时会自动创建。

3.1 数据库的创建、切换与查看

在MongoDB Shell中, use 命令用于切换数据库。如果数据库不存在,则会在第一次插入数据时创建它。

// 切换到名为‘shop’的数据库,如果不存在则标记为待创建
use shop
// 查看当前正在使用的数据库
db
// 查看所有数据库(只会显示有数据的库)
show dbs

这里有个关键点: show dbs 不会显示空数据库。你刚执行 use shop 后立即执行 show dbs ,是看不到 shop 的。必须至少插入一个文档后,它才会出现。

3.2 集合的创建与管理

集合类似于关系型数据库中的表。你可以显式创建,也可以隐式创建。

// 显式创建一个带有选项的集合(例如,创建固定大小的集合)
db.createCollection("logs", { capped: true, size: 100000, max: 1000 })
// 这个命令创建了一个“封顶集合”(capped collection),大小约100KB,最多存储1000个文档。当空间用尽或达到文档上限,最老的文档会被自动覆盖。非常适合存储日志、实时消息流。

// 隐式创建:直接向一个不存在的集合插入数据
db.products.insertOne({ name: "Laptop", price: 999.99 })
// 执行后,‘products’集合就被自动创建了。

// 查看当前数据库中的所有集合
show collections
// 删除一个集合(危险操作!)
db.products.drop()

注意 :对于生产环境,我强烈建议即使是普通集合,也最好通过 db.createCollection() 显式创建。因为这样可以提前设置一些重要选项,比如指定文档验证规则( validator ),为集合未来的行为定下规矩,避免后期插入脏数据。

4. 文档的CRUD操作:与数据对话的核心

这是MongoDB操作的重中之重。MongoDB的文档是BSON格式(Binary JSON),支持丰富的数据类型,包括嵌套对象和数组。

4.1 插入文档: insertOne insertMany

单条插入使用 insertOne ,批量插入使用 insertMany 。批量插入的效率远高于循环单条插入。

// 插入单条文档
db.users.insertOne({
  username: "alice",
  email: "alice@example.com",
  age: 30,
  address: {
    city: "New York",
    street: "5th Ave"
  },
  tags: ["developer", "mongodb"],
  createdAt: new Date() // 使用Date类型
})
// 插入成功后,MongoDB会自动为文档添加一个唯一的 `_id` 字段。

// 批量插入文档
db.orders.insertMany([
  { product: "A", quantity: 10, status: "pending" },
  { product: "B", quantity: 5, status: "shipped" },
  { product: "A", quantity: 20, status: "pending" }
])
// `insertMany` 默认是有序插入。如果中间某条文档插入失败(如主键冲突),其后的所有插入都会停止。你可以设置 `{ ordered: false }` 来尝试无序插入,即使部分失败,其他文档也会继续尝试插入。

4.2 查询文档:从基础到高级

查询是数据库操作中最频繁的部分。MongoDB的查询语法非常直观。

基础查询:

// 查找所有文档
db.users.find()
// 格式化美观地输出
db.users.find().pretty()

// 带条件的查询:查找 age 等于 30 的用户
db.users.find({ age: 30 })
// 查找 age 大于 25 的用户
db.users.find({ age: { $gt: 25 } })
// 查找 city 是 “New York” 的用户(查询嵌套字段)
db.users.find({ "address.city": "New York" })
// 查找 tags 数组包含 “mongodb” 的用户
db.users.find({ tags: "mongodb" })

投影(Projection): 只返回需要的字段,减少网络传输和数据解析开销。

// 只返回 username 和 email 字段,不返回 _id
db.users.find({}, { username: 1, email: 1, _id: 0 })
// 1 表示包含,0 表示排除。除了 _id,不能混用 1 和 0。

高级查询操作符: 这是MongoDB查询强大之处。

// $in: 匹配多个值
db.users.find({ age: { $in: [25, 30, 35] } })

// $and, $or: 逻辑运算
db.users.find({
  $and: [
    { age: { $gt: 25 } },
    { "address.city": "New York" }
  ]
})
// 等价于
db.users.find({ age: { $gt: 25 }, "address.city": "New York" })

db.users.find({
  $or: [
    { age: { $lt: 20 } },
    { age: { $gt: 40 } }
  ]
})

// $regex: 正则表达式查询(慎用,性能较差)
db.users.find({ username: { $regex: /^ali/i } }) // 查找用户名以‘ali’开头的用户,不区分大小写

// $elemMatch: 匹配数组中的元素满足所有条件
db.scores.insertMany([
  { student: "A", scores: [ { subject: "math", grade: 80 }, { subject: "english", grade: 90 } ] },
  { student: "B", scores: [ { subject: "math", grade: 70 }, { subject: "english", grade: 85 } ] }
])
// 查找数学成绩大于75分的学生
db.scores.find({ scores: { $elemMatch: { subject: "math", grade: { $gt: 75 } } } })

4.3 更新文档: updateOne , updateMany , replaceOne

更新操作需要特别注意,MongoDB的更新默认是“部分更新”。

// updateOne: 更新匹配的第一条文档
// 将用户 alice 的年龄改为 31
db.users.updateOne(
  { username: "alice" },
  { $set: { age: 31 } } // 使用 $set 操作符,只更新指定字段
)

// 如果不用 $set,会替换整个文档(危险!)
// db.users.updateOne({ username: "alice" }, { age: 31 }) // 这将导致文档只剩下 { _id: xxx, age: 31 }

// 其他常用更新操作符:
// $inc: 增加/减少数值
db.products.updateOne({ name: "Laptop" }, { $inc: { stock: -1 } }) // 库存减1
// $push: 向数组追加元素
db.users.updateOne({ username: "alice" }, { $push: { tags: "gamer" } })
// $addToSet: 向数组添加元素,仅当元素不存在时(避免重复)
db.users.updateOne({ username: "alice" }, { $addToSet: { tags: "developer" } }) // 不会重复添加
// $pull: 从数组中移除匹配的元素
db.users.updateOne({ username: "alice" }, { $pull: { tags: "gamer" } })

// updateMany: 更新所有匹配的文档
// 将所有状态为“pending”的订单数量增加1
db.orders.updateMany(
  { status: "pending" },
  { $inc: { quantity: 1 } }
)

// replaceOne: 完全替换匹配的第一个文档(保留 _id)
db.users.replaceOne(
  { username: "alice" },
  { username: "alice", fullName: "Alice Cooper", email: "newalice@example.com" } // 新文档
)

4.4 删除文档: deleteOne deleteMany

删除操作不可逆,务必谨慎,最好先使用 find 确认要删除的数据。

// 删除第一条匹配的文档
db.users.deleteOne({ age: { $lt: 18 } })
// 删除所有匹配的文档
db.logs.deleteMany({ createdAt: { $lt: new Date("2024-01-01") } }) // 删除2024年之前的日志
// 删除集合内所有文档(清空集合)
db.orders.deleteMany({})
// 与 `db.orders.drop()` 的区别:`deleteMany({})` 清空文档但保留集合和索引;`drop()` 删除整个集合。

5. 聚合框架:数据分析的瑞士军刀

当简单的 find 无法满足复杂的数据处理需求时,聚合管道(Aggregation Pipeline)就派上用场了。它允许你将文档通过一个由多个“阶段(Stage)”组成的管道,每个阶段对数据进行一次变换。这是MongoDB最强大的功能之一。

5.1 聚合管道核心阶段解析

一个典型的聚合管道看起来像这样:

db.orders.aggregate([
  { $match: { status: "completed", date: { $gte: ISODate("2024-10-01") } } }, // 阶段1:筛选
  { $group: { _id: "$product", totalQuantity: { $sum: "$quantity" }, averagePrice: { $avg: "$price" } } }, // 阶段2:分组统计
  { $sort: { totalQuantity: -1 } }, // 阶段3:排序
  { $limit: 10 } // 阶段4:限制输出
])

常用阶段详解:

  • $match :过滤文档,相当于 find 务必放在管道前端 ,可以尽早减少后续阶段要处理的文档数量,极大提升性能。
  • $group :分组统计,是聚合的核心。 _id 字段定义了分组的依据。可以使用 $sum , $avg , $min , $max , $first , $last , $push 等累加器。
  • $project :重塑文档结构,选择、重命名、计算新字段。功能比 find 的投影强大得多。
    db.users.aggregate([
      {
        $project: {
          fullName: { $concat: ["$firstName", " ", "$lastName"] }, // 计算字段
          email: 1,
          yearOfBirth: { $subtract: [2024, "$age"] } // 计算出生年份
        }
      }
    ])
    
  • $sort :排序。注意,排序操作需要内存,如果数据量巨大可能需要在 $sort 前使用 $limit 或确保有索引支持。
  • $limit / $skip :分页常用组合。但 $skip 在大数据量时性能很差,因为它需要扫描并跳过指定数量的文档。更好的分页方案是使用基于范围(如 _id 或时间戳)的查询。
  • $lookup :实现类似SQL的“左连接”。这是处理关联查询的关键。
    // 假设有 orders 和 products 两个集合
    db.orders.aggregate([
      {
        $lookup: {
          from: "products",         // 要连接的目标集合
          localField: "productId",  // 本地集合的关联字段
          foreignField: "_id",      // 目标集合的关联字段
          as: "productDetails"     // 输出数组字段名
        }
      },
      { $unwind: "$productDetails" } // 将数组展开为子文档(如果是一对一关系)
    ])
    
  • $unwind :将数组字段中的每个元素拆分成独立的文档。常用于对数组内容进行分组统计。

5.2 聚合查询性能优化实战

聚合管道虽然强大,但编写不当很容易导致性能问题。

  1. 顺序至关重要 :把能减少数据量的阶段(如 $match , $project )尽量往前放。在 $group 之前使用 $match 过滤无关数据,效率提升是数量级的。
  2. 警惕 $group 的内存使用 $group _id 字段如果基数(不同值的数量)非常大,会消耗大量内存。MongoDB默认允许聚合使用100MB内存,超过会报错。可以通过 allowDiskUse: true 选项允许使用磁盘,但这会显著变慢。根本解决方法是优化数据模型或分阶段聚合。
  3. 利用索引 :聚合管道中的 $match $sort 阶段如果能命中索引,速度会飞快。使用 explain() 方法可以查看聚合管道的执行计划,判断是否使用了索引。
    db.orders.aggregate([
      { $match: { status: "completed", date: { $gte: ISODate("2024-10-01") } } },
      { $sort: { totalAmount: -1 } }
    ]).explain("executionStats") // 查看执行详情
    
    针对这个管道,最好的索引是 { status: 1, date: 1, totalAmount: 1 } { status: 1, date: 1 } { totalAmount: 1 } 的复合索引。

6. 索引机制与查询优化:让查询飞起来

没有索引的数据库查询,就像在图书馆里找一本没有编号的书——只能从头到尾遍历。索引是数据库性能的命脉。

6.1 索引的创建与类型

// 1. 单字段索引:在 age 字段上创建升序索引
db.users.createIndex({ age: 1 }) // 1 为升序,-1 为降序。对于等值查询,顺序无关;对于排序和范围查询,方向有影响。

// 2. 复合索引:在多个字段上创建索引
db.orders.createIndex({ status: 1, createdAt: -1 })
// 这个索引能高效支持以下查询:
// db.orders.find({ status: "pending" }).sort({ createdAt: -1 })
// db.orders.find({ status: "pending", createdAt: { $gt: someDate } })
// 但无法高效支持:db.orders.find({ createdAt: { $gt: someDate } }) // 因为不符合“最左前缀”原则

// 3. 多键索引:在数组字段上创建索引
db.products.createIndex({ tags: 1 })
// 可以高效查询:db.products.find({ tags: "electronics" })

// 4. 文本索引:支持全文搜索
db.articles.createIndex({ content: "text", title: "text" })
// 查询:db.articles.find({ $text: { $search: "mongodb tutorial" } })

// 5. 哈希索引:用于哈希分片键,通常用于分片集群
db.users.createIndex({ _id: "hashed" })

// 查看集合的所有索引
db.users.getIndexes()
// 删除索引
db.users.dropIndex("age_1") // 通过索引名删除
db.users.dropIndex({ age: 1 }) // 通过索引键删除

6.2 “最左前缀”原则与索引设计策略

这是设计复合索引时最重要的原则。索引 { A: 1, B: 1, C: 1 } 可以被用于:

  • 查询条件包含 { A: ... }
  • 查询条件包含 { A: ..., B: ... }
  • 查询条件包含 { A: ..., B: ..., C: ... }
  • 排序 { A: 1 } , { A: 1, B: 1 } , { A: 1, B: 1, C: 1 } (方向需匹配或相反)

不能 被高效用于:

  • 查询条件只有 { B: ... } { C: ... }
  • 排序 { B: 1 }

我的索引设计经验:

  1. ESR原则 :对于复合索引,字段顺序按 E(Equality) - S(Sort) - R(Range) 排列。即,先放等值查询字段,再放排序字段,最后放范围查询字段。
    • 场景 :查询 db.orders.find({ status: "completed", createdAt: { $gte: ISODate("2024-10-01") } }).sort({ amount: -1 })
    • 最佳索引 { status: 1, amount: -1, createdAt: 1 }
    • 解释 status 是等值查询, amount 是排序字段, createdAt 是范围查询。
  2. 覆盖查询 :如果查询所需的所有字段都包含在索引中,MongoDB可以直接从索引返回结果,无需回表查询文档,速度极快。
    // 假设有索引 { username: 1, email: 1 }
    db.users.find({ username: "alice" }, { _id: 0, username: 1, email: 1 })
    // 这个查询可以被索引完全覆盖,性能最佳。
    
  3. 索引不是越多越好 :每个索引都会增加写操作(插入、更新、删除)的开销,因为数据变更时需要同步更新所有相关的索引。需要权衡读写比例。

6.3 使用 explain() 进行查询分析

当你发现某个查询很慢时, explain() 是你的第一诊断工具。

// 查看查询执行计划
db.orders.find({ status: "pending", totalAmount: { $gt: 100 } }).explain("executionStats")

重点关注输出中的:

  • winningPlan :MongoDB选择的执行计划。
  • stage COLLSCAN (集合扫描)意味着没走索引,性能差; IXSCAN (索引扫描)意味着走了索引,性能好。
  • executionStats.nReturned :返回的文档数。
  • executionStats.totalDocsExamined :扫描的文档数。理想情况下,这个数应该接近 nReturned 。如果远大于它,说明索引选择性不好或没用到索引。
  • executionStats.executionTimeMillis :执行时间。

通过分析这些信息,你可以判断是否需要创建新索引、修改现有索引或重写查询。

7. 实践中的高级主题与避坑指南

掌握了基本操作和索引,你已经能应对大部分场景。但在真实项目中,还有一些高级主题和“坑”需要特别注意。

7.1 事务处理:多文档操作的原子性

从MongoDB 4.0开始,支持了多文档ACID事务。这在需要跨多个文档或集合保证原子性时非常有用,比如银行转账。

const session = db.getMongo().startSession();
session.startTransaction();
try {
  const accounts = session.getDatabase('bank').accounts;
  accounts.updateOne({ _id: "A" }, { $inc: { balance: -100 } });
  accounts.updateOne({ _id: "B" }, { $inc: { balance: 100 } });
  session.commitTransaction();
  console.log("Transaction committed.");
} catch (error) {
  console.error("Transaction aborted due to error:", error);
  session.abortTransaction();
} finally {
  session.endSession();
}

重要提示 :事务有性能开销,并且只在副本集或分片集群中完全支持。对于大多数单文档操作,MongoDB本身就能保证原子性。不要滥用事务,只在必要时使用。

7.2 数据模型设计模式

MongoDB的灵活文档模型既是优势也是挑战。如何设计文档结构没有固定答案,但有一些常用模式:

  • 内嵌模式 :将关联紧密、一起查询的子数据直接内嵌在父文档中。适用于“一对少”且子数据不独立访问的场景。例如,博客文章和其评论。
  • 引用模式 :通过 ObjectId 引用其他集合的文档。适用于“一对多”或“多对多”关系,或者子数据需要独立查询、更新的场景。例如,用户和订单。
  • 桶模式 :将时间序列数据(如传感器读数)按时间窗口(如每小时、每天)分组到一个文档中。这能极大减少文档数量,提升查询和聚合效率。例如,将每分钟一条的IoT数据,聚合成每小时一个文档,数据存储在一个数组中。

7.3 连接池与驱动使用(以C#为例)

在应用程序中,千万不要为每次数据库操作都创建和关闭连接。一定要使用连接池。以C#的官方驱动为例:

using MongoDB.Driver;

// 正确做法:单例或依赖注入创建全局MongoClient
var connectionString = "mongodb://username:password@localhost:27017/myAppDB?authSource=admin";
var client = new MongoClient(connectionString); // MongoClient 是线程安全的,应全局复用
var database = client.GetDatabase("myAppDB");
var collection = database.GetCollection<BsonDocument>("myCollection");

// 使用 IQueryable 进行条件查询(对应热词:c# mongodb queryable 条件查询)
var filterBuilder = Builders<BsonDocument>.Filter;
var filter = filterBuilder.Gt("age", 25) & filterBuilder.Eq("city", "Beijing");
var results = collection.Find(filter).ToList();

// 或者使用 LINQ 风格的 IQueryable(需要定义强类型模型)
public class User {
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
var userCollection = database.GetCollection<User>("users");
var query = userCollection.AsQueryable().Where(u => u.Age > 25 && u.City == "Beijing").ToList();

连接字符串中的 authSource=admin 参数很重要,它指定了认证数据库。如果你的用户是在 admin 库创建的,这里就写 admin ;如果是在应用数据库(如 myAppDB )创建的,就写 myAppDB

7.4 常见错误与排查

  1. errmsg : not authorized on mydb to execute command :这是权限错误。说明当前连接的用户没有对目标数据库执行该命令的权限。检查用户名、密码、认证数据库和用户角色。
  2. 查询或聚合超时 :可能是数据量太大、没有索引、或聚合管道过于复杂。使用 explain() 分析,添加合适的索引,优化管道阶段顺序,考虑使用 $limit 限制中间结果集大小。
  3. 写入速度突然变慢 :检查磁盘I/O、内存使用情况。可能是索引过多导致写放大,或者达到了硬件瓶颈。监控 mongostat 或 Atlas 的性能指标。
  4. 内存使用过高 :MongoDB会尽可能利用可用内存来缓存数据和索引(WiredTiger缓存)。这是正常现象。但如果导致系统交换(swapping),就需要限制MongoDB的内存使用(通过 storage.wiredTiger.engineConfig.cacheSizeGB 配置)或增加物理内存。
  5. 关于“禁用zlib压缩” :WiredTiger存储引擎默认使用Snappy压缩。zlib压缩率更高但CPU消耗也更大。除非你的数据极其庞大且CPU资源充足,否则一般不需要调整。修改压缩算法是在启动参数或配置文件中设置 storage.wiredTiger.collectionConfig.blockCompressor storage.wiredTiger.indexConfig.prefixCompression 生产环境调整前务必充分测试

MongoDB的世界远不止于此,还有复制集(高可用)、分片集群(水平扩展)、Change Streams(变更流)、Atlas云服务等更高级的主题。但千里之行始于足下,牢牢掌握本文涵盖的核心操作、索引优化和实战经验,你已经具备了在项目中自信使用MongoDB的能力。记住,数据库操作的核心思想是相通的:理解你的数据、理解你的查询模式、然后设计合适的模型和索引。多动手实践,多查看官方文档,遇到问题时善用 explain() 和日志,你就能驾驭这个强大的现代数据平台。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值