事务和操作
对于事务
您可以在事务中创建集合和索引。有关详细信息,请参阅在事务中创建集合和索引
事务中使用的集合可以位于不同的数据库中。
注意
您不能在跨分片写事务中创建新的集合。例如,如果您在某个分片中写入现有集合,并在另一个分片中隐式创建集合,MongoDB无法在同一个事务中执行这两个操作。
您不能向受限集合写入。
您不能在
config
、admin
或local
数据库中的集合中读取/写入。您不能向
system.*
集合写入。您不能使用
explain
或类似命令返回支持的操作的查询计划。
您不能将
killCursors
命令作为事务的第一个操作。此外,如果您在事务中运行
killCursors
命令,服务器将立即停止指定的游标。它不会等待事务提交。
多文档事务中支持的操作
CRUD 操作
事务中允许以下读写操作
方法 | 命令 | 注意 |
---|---|---|
适用于非分片集合。 对于分片集合,请使用包含 $group 阶段的聚合管道。参见Distinct 操作. | ||
如果使用 有关更多详细信息,请参阅 管理操作。 | ||
如果在非存在的集合上运行,则将隐式创建该集合。 有关更多详细信息,请参阅 管理操作。 | ||
如果在非存在的集合上运行,则将隐式创建该集合。 有关更多详细信息,请参阅 管理操作。 | ||
如果在非存在的集合上运行,则将隐式创建该集合。 有关更多详细信息,请参阅 管理操作。 |
注意
更新分片键值
您可以通过执行单文档更新/ findAndModify 操作(无论是作为事务还是作为 可重试写)来更新文档的分片键值(除非分片键字段是不可变的 _id
字段)。有关详细信息,请参阅 更改文档的分片键值。
计数操作
要在事务中执行计数操作,请使用 $count
聚合阶段或 $group
聚合阶段(带 $sum
表达式)。
MongoDB 驱动程序提供了一个集合级别的 API countDocuments(filter, options)
作为辅助方法,它使用 $group
与 $sum
表达式来执行计数。
mongosh
提供了 db.collection.countDocuments()
辅助方法,该方法使用 $group
与 $sum
表达式来执行计数。
Distinct 操作
要在事务中执行 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"
.
有关在事务中创建集合和索引的更多信息,请参阅事务中的创建集合和索引。
隐式创建操作
您还可以通过以下对非现有集合的写操作隐式创建一个集合
针对非现有集合运行的方法 | 针对非现有集合运行的命令 |
---|---|
db.collection.findAndModify() 使用 upsert: true db.collection.findOneAndReplace() 使用 upsert: true db.collection.findOneAndUpdate() 使用 upsert: true | 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操作。
有关在事务中创建集合和索引的更多信息,请参阅事务中的创建集合和索引。
信息操作
信息命令,如 hello
,buildInfo
,connectionStatus
(及其辅助方法)允许在事务中使用;然而,它们不能是事务中的第一个操作。
受限操作
以下操作不允许在事务中使用
在跨分片写事务中创建新集合。例如,如果您在一个分片中对现有集合进行写操作并隐式地在不同分片创建一个集合,MongoDB无法在同一事务中执行这两个操作。
显式创建集合,例如
db.createCollection()
方法,以及索引,例如db.collection.createIndexes()
和db.collection.createIndex()
方法,当使用除"local"
之外的读取关注级别时。listCollections
和listIndexes
命令及其辅助方法。其他非CRUD和非信息性操作,如
createUser
,getParameter
,count
等,及其辅助方法。