文档菜单
文档首页
/
MongoDB 手册
/

事务和操作

在本页

  • 多文档事务中支持的操作
  • CRUD 操作
  • 计数操作
  • Distinct 操作
  • 管理操作
  • 信息操作
  • 受限操作

对于事务

  • 您可以在事务中创建集合和索引。有关详细信息,请参阅在事务中创建集合和索引

  • 事务中使用的集合可以位于不同的数据库中。

    注意

    您不能在跨分片写事务中创建新的集合。例如,如果您在某个分片中写入现有集合,并在另一个分片中隐式创建集合,MongoDB无法在同一个事务中执行这两个操作。

  • 您不能向受限集合写入。

  • 您不能在从受限集合读取时使用读取关注点"快照"。(从MongoDB 5.0开始)

  • 您不能在configadminlocal数据库中的集合中读取/写入。

  • 您不能向system.*集合写入。

  • 您不能使用explain或类似命令返回支持的操作的查询计划。

  • 对于在事务外创建的游标,您不能在事务内调用getMore

  • 对于在事务中创建的游标,您不能在事务外调用getMore

  • 您不能将killCursors命令作为事务的第一个操作。

    此外,如果您在事务中运行killCursors命令,服务器将立即停止指定的游标。它不会等待事务提交。

事务中允许以下读写操作

方法
命令
注意

排除以下查询操作表达式

该方法使用 $match 聚合阶段进行查询,以及 $group 聚合阶段和 $sum 表达式来执行计数。

适用于非分片集合。

对于分片集合,请使用包含 $group 阶段的聚合管道。参见Distinct 操作.

如果使用 upsert: true 在不存在的集合上运行更新或替换操作,则将隐式创建该集合。

有关更多详细信息,请参阅 管理操作。

如果在非存在的集合上运行,则将隐式创建该集合。

有关更多详细信息,请参阅 管理操作。

如果在非存在的集合上运行,则将隐式创建该集合。

有关更多详细信息,请参阅 管理操作。

如果在非存在的集合上运行,则将隐式创建该集合。

有关更多详细信息,请参阅 管理操作。

注意

更新分片键值

您可以通过执行单文档更新/ findAndModify 操作(无论是作为事务还是作为 可重试写)来更新文档的分片键值(除非分片键字段是不可变的 _id 字段)。有关详细信息,请参阅 更改文档的分片键值。

要在事务中执行计数操作,请使用 $count 聚合阶段或 $group 聚合阶段(带 $sum 表达式)。

MongoDB 驱动程序提供了一个集合级别的 API countDocuments(filter, options) 作为辅助方法,它使用 $group$sum 表达式来执行计数。

mongosh 提供了 db.collection.countDocuments() 辅助方法,该方法使用 $group$sum 表达式来执行计数。

要在事务中执行 Distinct 操作

  • 对于未分片的集合,您可以同时使用 db.collection.distinct() 方法/ distinct 命令以及包含 $group 阶段的聚合管道。

  • 对于分片集合,不能使用 db.collection.distinct() 方法或 distinct 命令。

    要查找分片集合的唯一值,请使用带有 $group 阶段的聚合管道。例如

    • 不要使用 db.coll.distinct("x"),使用

      db.coll.aggregate([
      { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
      { $project: { _id: 0 } }
      ])
    • 不要使用 db.coll.distinct("x", { status: "A" }),使用

      db.coll.aggregate([
      { $match: { status: "A" } },
      { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
      { $project: { _id: 0 } }
      ])

    管道返回一个指向文档的游标

    { "distinctValues" : [ 2, 3, 1 ] }

    迭代游标以访问结果文档。

如果事务不是跨分片写事务,则可以在 分布式事务 内创建集合和索引。不是 跨分片写事务。

命令
方法
注意
要创建的索引必须位于不存在的集合上,在这种情况下,集合将在操作过程中创建,或者位于同一事务中较早创建的新空集合上。

注意

要在事务内显式创建集合或索引,事务的读取关注级别必须是 "local".

有关在事务中创建集合和索引的更多信息,请参阅事务中的创建集合和索引。

您还可以通过以下对非现有集合的写操作隐式创建一个集合

针对非现有集合运行的方法
针对非现有集合运行的命令
findAndModify 使用 upsert: true
db.collection.updateOne() 使用 upsert: true
db.collection.updateMany() 使用 upsert: true
db.collection.replaceOne() 使用 upsert: true
update 使用 upsert: true
db.collection.bulkWrite() 使用插入或 upsert:true 操作
带有插入或 upsert:true 操作的各种 批量操作方法

有关事务中允许的其他CRUD操作,请参阅 CRUD操作。

有关在事务中创建集合和索引的更多信息,请参阅事务中的创建集合和索引。

信息命令,如 hellobuildInfoconnectionStatus(及其辅助方法)允许在事务中使用;然而,它们不能是事务中的第一个操作。

以下操作不允许在事务中使用

提示

另请参阅

返回

驱动器 API