事务和操作
对于事务:
您可以在事务中创建集合和索引。 有关详细信息,请参阅在事务中创建集合和索引
事务中使用的集合可以位于不同的数据库中。
注意
您无法在跨分片写事务中创建新集合。例如,如果您在一个分片中写入一个现有集合,并在另一个分片中隐式创建一个集合,MongoDB 将无法在同一事务中执行这两个操作。
不能写入固定大小集合。
从固定大小集合中读取时,无法使用读关注
"snapshot"
。(从 MongoDB 5.0 开始)不能在
config
、admin
或local
数据库中读取/写入集合。不能写入
system.*
集合。不能使用
explain
或类似命令返回受支持操作的查询计划。
不能将
killCursors
命令指定为ACID 事务中的第一个操作。此外,如果在ACID 事务中运行
killCursors
命令,服务器会立即停止指定的游标。它不会等待ACID 事务提交。
多文档事务中支持的操作
增删改查操作
允许在事务中执行以下读/写操作:
方法 | 命令 | 注意 |
---|---|---|
可用于未分片的集合。 For sharded collections, use the aggregation pipeline with the
$group stage. See Distinct Operation. | ||
如果使用 | ||
如果在不存在的集合上运行,则会隐式创建该集合。 | ||
如果在不存在的集合上运行,则会隐式创建该集合。 | ||
如果在不存在的集合上运行,则会隐式创建该集合。 |
注意
分片键值的更新
您可以通过在事务中或作为可重试写入发出单个文档 update/findAndModify 操作来更新文档的分片键值(除非分片键字段是不可变的 _id
字段)。有关详细信息,请参阅更改文档的分片键值。
计数操作
要在事务内执行计数操作,请使用 $count
聚合阶段或 $group
(带有 $sum
表达式)聚合阶段。
MongoDB 驱动程序提供集合级 API countDocuments(filter, options)
作为辅助方法,该方法使用 $group
和 $sum
表达式来执行计数。
mongosh
提供 db.collection.countDocuments()
辅助方法,该方法使用 $group
和 $sum
表达式进行计数。
去重操作
如要在事务中执行不同的操作:
对于未分片的集合,可以使用
db.collection.distinct()
方法/distinct
命令以及带有$group
阶段的聚合管道。对于分片集合,不能使用
db.collection.distinct()
方法或distinct
命令。要查找分片集合的不同值,请改用带有
$group
阶段的 aggregation pipeline。例如:不使用
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"
。
有关在事务中创建集合和索引的更多信息,请参阅在事务中创建集合和索引。
隐式创建操作
您还可以通过以下针对不存在的集合的写操作隐式创建集合:
针对不存在的集合的运行方法 | 针对非现有集合运行命令 |
---|---|
db.collection.findAndModify() with upsert: true db.collection.findOneAndReplace() with upsert: true db.collection.findOneAndUpdate() with upsert: true |
|
db.collection.updateOne() with upsert: true db.collection.updateMany() with upsert: true db.collection.replaceOne() with upsert: true |
|
db.collection.bulkWrite() with insert or upsert:true operationsVarious Bulk Operation Methods with insert or upsert:true operations |
有关事务中允许的其他 CRUD 操作,请参阅 CRUD 操作。
有关在事务中创建集合和索引的更多信息,请参阅在事务中创建集合和索引。
信息操作
事务中允许使用诸如 hello
、buildInfo
、connectionStatus
(及其辅助方法)之类的信息命令,但它们不能是事务中的第一项操作。
限制性操作
事务中不允许执行以下操作:
在跨分片写事务中创建新集合。例如,如果您在一个分片中写入一个现有集合,并在另一个分片中隐式创建一个集合,那么 MongoDB 将无法在同一事务中执行这两项操作。
显式创建集合 ,例如
db.createCollection()
方法,以及索引,例如db.collection.createIndexes()
和db.collection.createIndex()
方法(使用"local"
以外的读关注级别时)。listCollections
和listIndexes
命令及其辅助方法。其他非 CRUD 和非信息性操作(例如
createUser
、getParameter
和count
)及其辅助程序。