MongoDB技能指南Skill mongodb

本技能提供MongoDB文档数据库的全面指南,涵盖CRUD操作、聚合管道、索引优化、高可用性配置、安全措施和部署选项,适用于开发者和数据工程师,用于数据管理、后端开发和云原生应用。关键词:MongoDB, NoSQL, 数据库管理, 数据工程, 后端开发, 云原生

后端开发 0 次安装 0 次浏览 更新于 3/18/2026

名称:mongodb 描述:MongoDB实施指南 - 一个文档数据库平台,具有CRUD操作、聚合管道、索引、复制、分片、搜索能力和全面安全性。适用于使用MongoDB数据库、设计模式、编写查询、优化性能、配置部署(Atlas/自管理/Kubernetes)、实施安全或通过15+官方驱动程序集成应用程序时使用。(项目)

MongoDB 代理技能

一个全面的MongoDB工作指南 - 一个文档导向的数据库平台,提供强大的查询、水平扩展、高可用性和企业级安全性。

何时使用此技能

当您需要时使用此技能:

  • 设计MongoDB模式和数据模型
  • 编写CRUD操作和复杂查询
  • 构建聚合管道进行数据转换
  • 使用索引优化查询性能
  • 配置复制以实现高可用性
  • 设置分片以实现水平扩展
  • 实施安全(认证、授权、加密)
  • 部署MongoDB(Atlas、自管理、Kubernetes)
  • 通过15+官方驱动程序集成MongoDB与应用程序
  • 故障排除性能问题或错误
  • 实施Atlas搜索或向量搜索
  • 处理时间序列数据或变更流

文档覆盖范围

此技能综合了24,618个文档链接,横跨172个主要MongoDB部分,覆盖:

  • MongoDB版本5.0至8.1(即将发布)
  • 15+官方驱动程序语言
  • 50+集成工具(Kafka、Spark、BI连接器、Kubernetes操作符)
  • 完整的部署范围(Atlas云、自管理、Kubernetes)

I. 核心数据库操作

A. CRUD操作

读取操作

// 查找文档
db.collection.find({ status: "active" })
db.collection.findOne({ _id: ObjectId("...") })

// 查询运算符
db.users.find({ age: { $gte: 18, $lt: 65 } })
db.posts.find({ tags: { $in: ["mongodb", "database"] } })
db.products.find({ price: { $exists: true } })

// 投影(选择特定字段)
db.users.find({ status: "active" }, { name: 1, email: 1 })

// 游标操作
db.collection.find().sort({ createdAt: -1 }).limit(10).skip(20)

写入操作

// 插入
db.collection.insertOne({ name: "Alice", age: 30 })
db.collection.insertMany([{ name: "Bob" }, { name: "Charlie" }])

// 更新
db.users.updateOne(
  { _id: userId },
  { $set: { status: "verified" } }
)
db.users.updateMany(
  { lastLogin: { $lt: cutoffDate } },
  { $set: { status: "inactive" } }
)

// 替换整个文档
db.users.replaceOne({ _id: userId }, newUserDoc)

// 删除
db.users.deleteOne({ _id: userId })
db.users.deleteMany({ status: "deleted" })

// 更新或插入(如果不存在)
db.users.updateOne(
  { email: "user@example.com" },
  { $set: { name: "User", lastSeen: new Date() } },
  { upsert: true }
)

原子操作

// 递增计数器
db.posts.updateOne(
  { _id: postId },
  { $inc: { views: 1 } }
)

// 添加到数组(如果不存在)
db.users.updateOne(
  { _id: userId },
  { $addToSet: { interests: "mongodb" } }
)

// 推送到数组
db.posts.updateOne(
  { _id: postId },
  { $push: { comments: { author: "Alice", text: "Great!" } } }
)

// 原子查找和修改
db.counters.findAndModify({
  query: { _id: "sequence" },
  update: { $inc: { value: 1 } },
  new: true,
  upsert: true
})

B. 查询运算符(100+)

比较运算符

$eq, $ne, $gt, $gte, $lt, $lte
$in, $nin

逻辑运算符

$and, $or, $not, $nor

// 示例
db.products.find({
  $and: [
    { price: { $gte: 100 } },
    { stock: { $gt: 0 } }
  ]
})

数组运算符

$all, $elemMatch, $size
$firstN, $lastN, $maxN, $minN

// 示例:查找具有所有标签的文档
db.posts.find({ tags: { $all: ["mongodb", "database"] } })

// 匹配具有多个条件的数组元素
db.products.find({
  reviews: {
    $elemMatch: { rating: { $gte: 4 }, verified: true }
  }
})

存在性和类型

$exists, $type

// 查找具有可选字段的文档
db.users.find({ phoneNumber: { $exists: true } })

// 类型检查
db.data.find({ value: { $type: "string" } })

C. 聚合管道

MongoDB最强大的功能,用于数据转换和分析。

核心管道阶段(40+)

db.orders.aggregate([
  // 阶段1:过滤文档
  { $match: { status: "completed", total: { $gte: 100 } } },

  // 阶段2:与客户连接
  { $lookup: {
    from: "customers",
    localField: "customerId",
    foreignField: "_id",
    as: "customer"
  }},

  // 阶段3:展开数组
  { $unwind: "$items" },

  // 阶段4:分组和聚合
  { $group: {
    _id: "$items.category",
    totalRevenue: { $sum: "$items.total" },
    orderCount: { $sum: 1 },
    avgOrderValue: { $avg: "$total" }
  }},

  // 阶段5:排序结果
  { $sort: { totalRevenue: -1 } },

  // 阶段6:限制结果
  { $limit: 10 },

  // 阶段7:重塑输出
  { $project: {
    category: "$_id",
    revenue: "$totalRevenue",
    orders: "$orderCount",
    avgValue: { $round: ["$avgOrderValue", 2] },
    _id: 0
  }}
])

常见管道模式

基于时间的聚合:

db.events.aggregate([
  { $match: { timestamp: { $gte: startDate, $lt: endDate } } },
  { $group: {
    _id: {
      year: { $year: "$timestamp" },
      month: { $month: "$timestamp" },
      day: { $dayOfMonth: "$timestamp" }
    },
    count: { $sum: 1 }
  }}
])

多面搜索(多个聚合):

db.products.aggregate([
  { $match: { category: "electronics" } },
  { $facet: {
    priceRanges: [
      { $bucket: {
        groupBy: "$price",
        boundaries: [0, 100, 500, 1000, 5000],
        default: "5000+",
        output: { count: { $sum: 1 } }
      }}
    ],
    topBrands: [
      { $group: { _id: "$brand", count: { $sum: 1 } } },
      { $sort: { count: -1 } },
      { $limit: 5 }
    ],
    avgPrice: [
      { $group: { _id: null, avg: { $avg: "$price" } } }
    ]
  }}
])

窗口函数:

db.sales.aggregate([
  { $setWindowFields: {
    partitionBy: "$region",
    sortBy: { date: 1 },
    output: {
      runningTotal: { $sum: "$amount", window: { documents: ["unbounded", "current"] } },
      movingAvg: { $avg: "$amount", window: { documents: [-7, 0] } }
    }
  }}
])

聚合运算符(150+)

数学运算符:

$add, $subtract, $multiply, $divide, $mod
$abs, $ceil, $floor, $round, $sqrt, $pow
$log, $log10, $ln, $exp

字符串运算符:

$concat, $substr, $toLower, $toUpper
$trim, $ltrim, $rtrim, $split
$regexMatch, $regexFind, $regexFindAll

数组运算符:

$arrayElemAt, $slice, $first, $last, $reverse
$sortArray, $filter, $map, $reduce
$zip, $concatArrays

日期/时间运算符:

$dateAdd, $dateDiff, $dateFromString, $dateToString
$dayOfMonth, $month, $year, $dayOfWeek
$week, $hour, $minute, $second

类型转换:

$toInt, $toString, $toDate, $toDouble
$toDecimal, $toObjectId, $toBool

II. 索引和性能

A. 索引类型

单字段索引

db.users.createIndex({ email: 1 })  // 升序
db.posts.createIndex({ createdAt: -1 })  // 降序

复合索引

// 顺序重要!索引在 { status: 1, createdAt: -1 }
db.orders.createIndex({ status: 1, createdAt: -1 })

// 支持查询:
// - { status: "..." }
// - { status: "...", createdAt: ... }
// 不有效支持:{ createdAt: ... } 单独

文本索引(全文搜索)

db.articles.createIndex({ title: "text", body: "text" })

// 搜索
db.articles.find({ $text: { $search: "mongodb database" } })

// 带有相关性分数
db.articles.find(
  { $text: { $search: "mongodb" } },
  { score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } })

地理空间索引

// 2dsphere用于类地球几何
db.places.createIndex({ location: "2dsphere" })

// 查找附近
db.places.find({
  location: {
    $near: {
      $geometry: { type: "Point", coordinates: [lon, lat] },
      $maxDistance: 5000  // 米
    }
  }
})

通配符索引

// 索引子文档中的所有字段
db.products.createIndex({ "attributes.$**": 1 })

// 支持对属性下任何字段的查询
db.products.find({ "attributes.color": "red" })

部分索引

// 仅索引匹配过滤器的文档
db.orders.createIndex(
  { customerId: 1 },
  { partialFilterExpression: { status: "active" } }
)

TTL索引(自动删除)

// 在创建后24小时删除文档
db.sessions.createIndex(
  { createdAt: 1 },
  { expireAfterSeconds: 86400 }
)

哈希索引(用于分片)

db.users.createIndex({ userId: "hashed" })

B. 查询优化

解释查询计划

// 基本解释
db.users.find({ email: "user@example.com" }).explain()

// 执行统计(显示实际性能)
db.users.find({ age: { $gte: 18 } }).explain("executionStats")

// 检查关键指标:
// - executionTimeMillis
// - totalDocsExamined vs. nReturned(应接近)
// - stage: "IXSCAN"(使用索引)vs. "COLLSCAN"(全扫描 - 不好)

覆盖查询

// 创建索引
db.users.createIndex({ email: 1, name: 1 })

// 查询被索引覆盖(无需文档获取)
db.users.find(
  { email: "user@example.com" },
  { email: 1, name: 1, _id: 0 }  // 仅投影索引字段
)

索引提示

// 强制特定索引
db.users.find({ status: "active", city: "NYC" })
  .hint({ status: 1, createdAt: -1 })

索引管理

// 列出所有索引
db.collection.getIndexes()

// 删除索引
db.collection.dropIndex("indexName")

// 隐藏索引(在删除前测试)
db.collection.hideIndex("indexName")
db.collection.unhideIndex("indexName")

// 索引统计
db.collection.aggregate([{ $indexStats: {} }])

III. 数据建模模式

A. 关系模式

一对一(嵌入)

// 具有单个地址的用户
{
  _id: ObjectId("..."),
  name: "Alice",
  email: "alice@example.com",
  address: {
    street: "123 Main St",
    city: "NYC",
    zipcode: "10001"
  }
}

一对少(嵌入数组)

// 博客文章与评论(< 100评论)
{
  _id: ObjectId("..."),
  title: "MongoDB指南",
  comments: [
    { author: "Bob", text: "Great post!", date: ISODate("...") },
    { author: "Charlie", text: "Thanks!", date: ISODate("...") }
  ]
}

一对多(引用)

// 作者集合
{ _id: ObjectId("author1"), name: "Alice" }

// 书籍集合(每个作者多本书)
{ _id: ObjectId("book1"), title: "Book 1", authorId: ObjectId("author1") }
{ _id: ObjectId("book2"), title: "Book 2", authorId: ObjectId("author1") }

多对多(引用数组)

// 用户集合
{
  _id: ObjectId("user1"),
  name: "Alice",
  groupIds: [ObjectId("group1"), ObjectId("group2")]
}

// 组集合
{
  _id: ObjectId("group1"),
  name: "MongoDB用户",
  memberIds: [ObjectId("user1"), ObjectId("user2")]
}

B. 高级模式

时间序列模式

// 高频传感器数据
{
  _id: ObjectId("..."),
  sensorId: "sensor-123",
  timestamp: ISODate("2025-01-01T00:00:00Z"),
  readings: [
    { time: 0, temp: 23.5, humidity: 45 },
    { time: 60, temp: 23.6, humidity: 46 },
    { time: 120, temp: 23.4, humidity: 45 }
  ]
}

// 创建时间序列集合
db.createCollection("sensor_data", {
  timeseries: {
    timeField: "timestamp",
    metaField: "sensorId",
    granularity: "minutes"
  }
})

计算模式(缓存结果)

// 用户文档带有预计算统计
{
  _id: ObjectId("..."),
  username: "alice",
  stats: {
    postCount: 150,
    followerCount: 2500,
    lastUpdated: ISODate("...")
  }
}

// 定期或用触发器更新统计

模式版本控制

// 支持模式演变
{
  _id: ObjectId("..."),
  schemaVersion: 2,
  // v2字段
  name: { first: "Alice", last: "Smith" },
  // 迁移代码处理v1格式
}

C. 模式验证

db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["email", "name"],
      properties: {
        email: {
          bsonType: "string",
          pattern: "^.+@.+$",
          description: "must be a valid email"
        },
        age: {
          bsonType: "int",
          minimum: 0,
          maximum: 120
        },
        status: {
          enum: ["active", "inactive", "pending"]
        }
      }
    }
  },
  validationLevel: "strict",  // 或 "moderate"
  validationAction: "error"   // 或 "warn"
})

IV. 复制和高可用性

A. 副本集

架构:

  • 主节点:接受写入,复制到从节点
  • 从节点:复制主节点的操作日志,可提供读取
  • 仲裁节点:在选举中投票,不保存数据

配置:

rs.initiate({
  _id: "myReplicaSet",
  members: [
    { _id: 0, host: "mongo1:27017" },
    { _id: 1, host: "mongo2:27017" },
    { _id: 2, host: "mongo3:27017" }
  ]
})

// 检查状态
rs.status()

// 添加成员
rs.add("mongo4:27017")

// 移除成员
rs.remove("mongo4:27017")

B. 写入关注

控制写入操作的确认:

// 等待大多数确认(持久)
db.users.insertOne(
  { name: "Alice" },
  { writeConcern: { w: "majority", wtimeout: 5000 } }
)

// 常见级别:
// w: 1 - 主节点确认(默认)
// w: "majority" - 多数节点确认(生产推荐)
// w: <number> - 特定节点数
// w: 0 - 无确认(发射后不管)

C. 读取偏好

控制读取从哪里提供:

// 选项:
// - primary(默认):仅从主节点读取
// - primaryPreferred:主节点如果可用,否则从节点
// - secondary:仅从从节点读取
// - secondaryPreferred:从节点如果可用,否则主节点
// - nearest:最低网络延迟

db.collection.find().readPref("secondaryPreferred")

D. 事务

多文档ACID事务:

const session = client.startSession();
session.startTransaction();

try {
  await accounts.updateOne(
    { _id: fromAccount },
    { $inc: { balance: -amount } },
    { session }
  );

  await accounts.updateOne(
    { _id: toAccount },
    { $inc: { balance: amount } },
    { session }
  );

  await session.commitTransaction();
} catch (error) {
  await session.abortTransaction();
  throw error;
} finally {
  session.endSession();
}

V. 分片和水平扩展

A. 分片集群架构

组件:

  • 分片: 保存数据子集的副本集
  • 配置服务器: 存储集群元数据
  • Mongos: 查询路由器,将操作定向到分片

B. 分片键选择

关键: 分片键决定数据分布和查询性能。

好的分片键:

  • 高基数(许多唯一值)
  • 均匀分布(无热点)
  • 与查询对齐(查询包括分片键)
// 在数据库上启用分片
sh.enableSharding("myDatabase")

// 用哈希键分片集合
sh.shardCollection(
  "myDatabase.users",
  { userId: "hashed" }
)

// 用复合键分片
sh.shardCollection(
  "myDatabase.orders",
  { customerId: 1, orderDate: 1 }
)

C. 区域分片

将数据范围分配给特定分片:

// 添加分片标签
sh.addShardTag("shard0", "US-EAST")
sh.addShardTag("shard1", "US-WEST")

// 将范围分配给区域
sh.addTagRange(
  "myDatabase.users",
  { zipcode: "00000" },
  { zipcode: "50000" },
  "US-EAST"
)

D. 查询路由

// 目标查询(包括分片键) - 快速
db.users.find({ userId: "12345" })

// 分散收集(无分片键) - 慢速
db.users.find({ email: "user@example.com" })

VI. 安全

A. 认证

方法:

  1. SCRAM(用户名/密码) - 默认
  2. X.509证书 - 相互TLS
  3. LDAP(企业版)
  4. Kerberos(企业版)
  5. AWS IAM
  6. OIDC(OpenID Connect)
// 创建管理员用户
use admin
db.createUser({
  user: "admin",
  pwd: "strongPassword",
  roles: ["root"]
})

// 创建数据库用户
use myDatabase
db.createUser({
  user: "appUser",
  pwd: "password",
  roles: [
    { role: "readWrite", db: "myDatabase" }
  ]
})

B. 基于角色的访问控制(RBAC)

内置角色:

  • read, readWrite:集合级别
  • dbAdmin, dbOwner:数据库管理
  • userAdmin:用户管理
  • clusterAdmin:集群管理
  • root:超级用户

自定义角色:

db.createRole({
  role: "customRole",
  privileges: [
    {
      resource: { db: "myDatabase", collection: "users" },
      actions: ["find", "update"]
    }
  ],
  roles: []
})

C. 加密

静态加密

// 在mongod.conf中配置
security:
  enableEncryption: true
  encryptionKeyFile: /path/to/keyfile

传输加密(TLS/SSL)

// mongod.conf
net:
  tls:
    mode: requireTLS
    certificateKeyFile: /path/to/cert.pem
    CAFile: /path/to/ca.pem

客户端字段级加密(CSFLE)

// 敏感字段的自动加密
const clientEncryption = new ClientEncryption(client, {
  keyVaultNamespace: "encryption.__keyVault",
  kmsProviders: {
    aws: {
      accessKeyId: "...",
      secretAccessKey: "..."
    }
  }
})

// 创建数据键
const dataKeyId = await clientEncryption.createDataKey("aws", {
  masterKey: { region: "us-east-1", key: "..." }
})

// 配置自动加密
const encryptedClient = new MongoClient(uri, {
  autoEncryption: {
    keyVaultNamespace: "encryption.__keyVault",
    kmsProviders: { aws: {...} },
    schemaMap: {
      "myDatabase.users": {
        bsonType: "object",
        properties: {
          ssn: {
            encrypt: {
              keyId: [dataKeyId],
              algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
            }
          }
        }
      }
    }
  }
})

VII. 部署选项

A. MongoDB Atlas(云)

推荐大多数用例。

快速入门:

  1. 在mongodb.com/atlas创建免费M0集群
  2. 白名单IP地址
  3. 创建数据库用户
  4. 获取连接字符串

功能:

  • 自动扩展
  • 自动备份
  • 多云(AWS、Azure、GCP)
  • 多区域部署
  • Atlas搜索和向量搜索
  • 图表(嵌入式分析)
  • 数据联邦
  • 无服务器实例

连接:

const uri = "mongodb+srv://user:pass@cluster.mongodb.net/database?retryWrites=true&w=majority";
const client = new MongoClient(uri);

B. 自管理

安装:

# Ubuntu/Debian
wget -qO - https://www.mongodb.org/static/pgp/server-8.0.asc | sudo apt-key add -
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
sudo apt-get update
sudo apt-get install -y mongodb-org

# 启动
sudo systemctl start mongod
sudo systemctl enable mongod

配置(mongod.conf):

storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true

systemLog:
  destination: file
  path: /var/log/mongodb/mongod.log
  logAppend: true

net:
  port: 27017
  bindIp: 127.0.0.1

security:
  authorization: enabled

replication:
  replSetName: "myReplicaSet"

C. Kubernetes部署

MongoDB Kubernetes操作符:

apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: mongodb-replica-set
spec:
  members: 3
  type: ReplicaSet
  version: "8.0"
  security:
    authentication:
      modes: ["SCRAM"]
  users:
    - name: admin
      db: admin
      passwordSecretRef:
        name: mongodb-admin-password
      roles:
        - name: root
          db: admin
  statefulSet:
    spec:
      volumeClaimTemplates:
        - metadata:
            name: data-volume
          spec:
            accessModes: ["ReadWriteOnce"]
            resources:
              requests:
                storage: 10Gi

VIII. 集成和驱动程序

A. 官方驱动程序(15+语言)

Node.js

const { MongoClient } = require("mongodb");

const client = new MongoClient(uri);
await client.connect();

const db = client.db("myDatabase");
const collection = db.collection("users");

// CRUD
await collection.insertOne({ name: "Alice" });
const user = await collection.findOne({ name: "Alice" });
await collection.updateOne({ name: "Alice" }, { $set: { age: 30 } });
await collection.deleteOne({ name: "Alice" });

Python(PyMongo)

from pymongo import MongoClient

client = MongoClient(uri)
db = client.myDatabase
collection = db.users

# CRUD
collection.insert_one({"name": "Alice"})
user = collection.find_one({"name": "Alice"})
collection.update_one({"name": "Alice"}, {"$set": {"age": 30}})
collection.delete_one({"name": "Alice"})

Java

MongoClient mongoClient = MongoClients.create(uri);
MongoDatabase database = mongoClient.getDatabase("myDatabase");
MongoCollection<Document> collection = database.getCollection("users");

// 插入
collection.insertOne(new Document("name", "Alice"));

// 查找
Document user = collection.find(eq("name", "Alice")).first();

// 更新
collection.updateOne(eq("name", "Alice"), set("age", 30));

Go

client, _ := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
collection := client.Database("myDatabase").Collection("users")

// 插入
collection.InsertOne(context.TODO(), bson.M{"name": "Alice"})

// 查找
var user bson.M
collection.FindOne(context.TODO(), bson.M{"name": "Alice"}).Decode(&user)

B. 集成工具

Kafka连接器

{
  "connector.class": "com.mongodb.kafka.connect.MongoSinkConnector",
  "connection.uri": "mongodb://localhost:27017",
  "database": "myDatabase",
  "collection": "events",
  "topics": "my-topic"
}

Spark连接器

val df = spark.read
  .format("mongodb")
  .option("uri", "mongodb://localhost:27017/myDatabase.myCollection")
  .load()

df.filter($"age" > 18).show()

BI连接器(SQL接口)

-- 使用SQL查询MongoDB
SELECT name, AVG(age) as avg_age
FROM users
WHERE status = 'active'
GROUP BY name;

IX. 高级功能

A. Atlas搜索(全文)

创建搜索索引:

{
  "mappings": {
    "dynamic": false,
    "fields": {
      "title": {
        "type": "string",
        "analyzer": "lucene.standard"
      },
      "description": {
        "type": "string",
        "analyzer": "lucene.english"
      }
    }
  }
}

查询:

db.articles.aggregate([
  {
    $search: {
      text: {
        query: "mongodb database",
        path: ["title", "description"],
        fuzzy: { maxEdits: 1 }
      }
    }
  },
  { $limit: 10 },
  { $project: { title: 1, description: 1, score: { $meta: "searchScore" } } }
])

B. Atlas向量搜索

用于AI/ML相似性搜索:

db.products.aggregate([
  {
    $vectorSearch: {
      index: "vector_index",
      path: "embedding",
      queryVector: [0.123, 0.456, ...],  // OpenAI的1536维度
      numCandidates: 100,
      limit: 10
    }
  },
  {
    $project: {
      name: 1,
      description: 1,
      score: { $meta: "vectorSearchScore" }
    }
  }
])

C. 变更流(实时)

const changeStream = collection.watch([
  { $match: { "fullDocument.status": "active" } }
]);

changeStream.on("change", (change) => {
  console.log("检测到变更:", change);
  // change.operationType: "insert", "update", "delete", "replace"
  // change.fullDocument: 完整文档(如果配置)
});

// 从特定点恢复
const resumeToken = changeStream.resumeToken;
const newStream = collection.watch([], { resumeAfter: resumeToken });

D. 批量操作

const bulkOps = [
  { insertOne: { document: { name: "Alice", age: 30 } } },
  { updateOne: {
    filter: { name: "Bob" },
    update: { $set: { age: 25 } },
    upsert: true
  }},
  { deleteOne: { filter: { name: "Charlie" } } }
];

const result = await collection.bulkWrite(bulkOps, { ordered: false });
console.log(`插入:${result.insertedCount}, 更新:${result.modifiedCount}`);

X. 性能优化

最佳实践

  1. 索引关键字段

    • 索引用于查询、排序、连接的字段
    • 监控慢查询(>100ms)
    • 为多字段查询使用复合索引
  2. 使用投影

    // 好:仅返回所需字段
    db.users.find({ status: "active" }, { name: 1, email: 1 })
    
    // 坏:返回整个文档
    db.users.find({ status: "active" })
    
  3. 限制结果集

    db.users.find().limit(100)
    
  4. 使用聚合管道

    • 在服务器端处理数据,而不是客户端
    • 早期使用 $match 过滤
    • 使用 $project 减少文档大小
  5. 连接池

    const client = new MongoClient(uri, {
      maxPoolSize: 50,
      minPoolSize: 10
    });
    
  6. 批量写入

    // 好:批量插入
    await collection.insertMany(documents);
    
    // 坏:单独插入
    for (const doc of documents) {
      await collection.insertOne(doc);
    }
    
  7. 写入关注调优

    • 使用 w: 1 用于非关键写入(更快)
    • 使用 w: "majority" 用于关键数据(更安全)
  8. 读取偏好

    • 使用 secondary 用于读取密集型分析
    • 使用 primary 用于强一致性

监控

// 检查慢查询
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(10)

// 当前操作
db.currentOp()

// 服务器状态
db.serverStatus()

// 集合统计
db.collection.stats()

XI. 故障排除

常见错误

错误 原因 解决方案
MongoNetworkError 连接失败 检查网络、IP白名单、凭据
E11000 duplicate key 重复唯一字段 检查唯一索引,处理重复
ValidationError 模式验证失败 检查文档结构、字段类型
OperationTimeout 查询太慢 添加索引、优化查询、增加超时
AggregationResultTooLarge 结果 > 16MB 使用 $limit$project$out
InvalidSharKey 坏的分片键 选择高基数、均匀分布的键
ChunkTooBig 巨块 使用 refineShardKey 或重新分片
OplogTailFailed 复制延迟 检查网络,增加操作日志大小

调试工具

// 解释查询计划
db.collection.find({ field: value }).explain("executionStats")

// 检查索引使用
db.collection.aggregate([{ $indexStats: {} }])

// 分析慢查询
db.setProfilingLevel(2)  // 分析所有查询
db.system.profile.find({ millis: { $gt: 100 } })

// 检查复制延迟
rs.printReplicationInfo()
rs.printSecondaryReplicationInfo()

XII. 快速参考

前20个操作(按频率)

  1. find() - 查询文档
  2. updateOne() / updateMany() - 修改文档
  3. insertOne() / insertMany() - 添加文档
  4. deleteOne() / deleteMany() - 移除文档
  5. aggregate() - 复杂查询
  6. createIndex() - 性能优化
  7. explain() - 查询分析
  8. findOne() - 获取单个文档
  9. countDocuments() - 计数匹配
  10. replaceOne() - 替换文档
  11. distinct() - 获取唯一值
  12. bulkWrite() - 批量操作
  13. findAndModify() - 原子更新
  14. watch() - 监控变更
  15. sort() / limit() / skip() - 结果操作
  16. $lookup - 连接集合
  17. $group - 聚合数据
  18. $match - 过滤管道
  19. $project - 塑造输出
  20. hint() - 强制索引

常见模式

分页:

const page = 2;
const pageSize = 20;
db.collection.find()
  .skip((page - 1) * pageSize)
  .limit(pageSize)

基于游标的分页(更好):

const lastId = ObjectId("...");
db.collection.find({ _id: { $gt: lastId } })
  .limit(20)

原子计数器:

db.counters.findAndModify({
  query: { _id: "sequence" },
  update: { $inc: { value: 1 } },
  new: true,
  upsert: true
})

软删除:

// 标记为已删除
db.users.updateOne({ _id: userId }, { $set: { deleted: true, deletedAt: new Date() } })

// 仅查询活跃
ndb.users.find({ deleted: { $ne: true } })

XIII. 资源

官方文档

工具

  • MongoDB Compass - MongoDB的GUI
  • MongoDB Shell (mongosh) - 现代shell
  • Atlas CLI - 自动化Atlas操作
  • 数据库工具 - mongodump、mongorestore、mongoimport

最佳实践摘要

  1. 始终使用索引 用于查询字段
  2. 嵌入 vs. 引用: 嵌入用于一对少,引用用于一对多
  3. 分片键: 高基数 + 均匀分布 + 与查询对齐
  4. 安全: 启用认证,使用TLS,为生产加密静态数据
  5. 复制: 至少3个节点用于高可用性
  6. 写入关注: w: "majority" 用于关键数据
  7. 监控: 跟踪慢查询、复制延迟、磁盘使用
  8. 测试: 使用explain()验证查询性能
  9. 连接池: 配置适当的池大小
  10. 模式验证: 定义模式以确保数据完整性

XIV. 版本特定功能

MongoDB 8.0(当前)

  • 配置分片(结合配置和分片角色)
  • 改进的聚合性能
  • 增强的安全功能

MongoDB 7.0

  • 自动合并块
  • 时间序列改进
  • 可查询加密GA

MongoDB 6.0

  • 重新分片支持
  • 集群集合
  • 时间序列集合改进

MongoDB 5.0

  • 时间序列集合
  • 实时重新分片
  • 版本化API

常见用例

电子商务

  • 产品目录(嵌入属性)
  • 订单(用于一致性的事务)
  • 用户会话(TTL索引用于清理)
  • 搜索(Atlas搜索用于产品)

IoT/时间序列

  • 传感器数据(时间序列集合)
  • 实时分析(变更流)
  • 保留策略(TTL索引)

社交网络

  • 用户档案(嵌入或引用)
  • 帖子和评论(小规模嵌入,大规模引用)
  • 实时订阅源(变更流)
  • 搜索(Atlas搜索用于内容)

分析

  • 事件跟踪(高写入吞吐量)
  • 聚合管道(复杂分析)
  • 数据联邦(跨源查询)

何时不使用MongoDB

  • 强调一致性而非可用性(使用传统RDBMS)
  • 复杂的多表连接(SQL数据库在此表现更好)
  • 极小的数据集(<1GB)且简单查询
  • 跨多个数据库的ACID事务(不支持)

此技能提供全面的MongoDB知识,用于实施数据库解决方案,从基本CRUD操作到高级分布式系统,包括分片、复制和安全。始终参考官方文档以获取最新功能和版本特定细节。