Docs HomeMongoDB Manual

Transactions and Operations事务和操作

For transactions:对于事务:

  • You can specify read/write (CRUD) operations on existing collections. 您可以在现有集合上指定读/写(CRUD)操作。For a list of CRUD operations, see CRUD Operations.有关CRUD操作的列表,请参阅CRUD操作
  • Starting in MongoDB 4.4, you can create collections and indexes in transactions. 从MongoDB 4.4开始,您可以在事务中创建集合和索引。For details, see Create Collections and Indexes In a Transaction有关详细信息,请参阅在事务中创建集合和索引
  • The collections used in a transaction can be in different databases.事务中使用的集合可以在不同的数据库中。

    Note

    You cannot create new collections in cross-shard write transactions. 不能在跨分片写入事务中创建新集合。For example, if you write to an existing collection in one shard and implicitly create a collection in a different shard, MongoDB cannot perform both operations in the same transaction.例如,如果您在一个分片中写入一个现有集合,并在另一个分片中隐式创建一个集合,则MongoDB无法在同一事务中执行这两个操作。

  • You cannot write to capped collections. (Starting in MongoDB 4.2)您不能写入封顶集合。(从MongoDB 4.2开始)
  • You cannot use read concern "snapshot" when reading from a capped collection. (Starting in MongoDB 5.0)封顶集合中读取时,不能使用读取关注点"snapshot"。(从MongoDB 5.0开始)
  • You cannot read/write to collections in the config, admin, or local databases.无法读取/写入configadminlocal数据库中的集合。
  • You cannot write to system.* collections.无法写入system.*集合。
  • You cannot return the supported operation's query plan (i.e. explain).无法返回支持的操作的查询计划(即explain)。
  • For cursors created outside of a transaction, you cannot call getMore inside the transaction.对于在事务外部创建的游标,不能在事务内部调用getMore
  • For cursors created in a transaction, you cannot call getMore outside the transaction.对于在事务中创建的游标,不能在事务外调用getMore

Operations that affect the database catalog, such as creating or dropping a collection or an index, are not allowed in multi-document transactions. 在多文档事务中,不允许执行影响数据库目录的操作,例如创建或删除集合或索引。For example, a multi-document transaction cannot include an insert operation that would result in the creation of a new collection. 例如,多文档事务不能包含会导致创建新集合的插入操作。See Restricted Operations.请参阅受限操作

Operations Supported in Multi-Document Transactions多文档事务中支持的操作

CRUD OperationsCRUD操作

The following read/write operations are allowed in transactions:事务中允许以下读/写操作:

Method方法Command命令Note备注
db.collection.aggregate()aggregateExcluding the following stages:不包括以下阶段:
db.collection.countDocuments()Excluding the following query operator expressions:排除以下查询运算符表达式: The method uses the $match aggregation stage for the query and $group aggregation stage with a $sum expression to perform the count. 该方法使用查询的$match聚合阶段和带有$sum表达式的$group聚合阶段来执行计数。
db.collection.distinct()distinctAvailable on unsharded collections. 可用于未排序的集合。
For sharded collections, use the aggregation pipeline with the $group stage. 对于分片集合,使用带有$group阶段的聚合管道。See Distinct Operation.请参见剔除重复项操作
db.collection.find()find
db.collection.deleteMany()
db.collection.deleteOne()
db.collection.remove()
delete
db.collection.findOneAndDelete()
db.collection.findOneAndReplace()
db.collection.findOneAndUpdate()
findAndModifyStarting in MongoDB 4.4, if the update or replace operation is run with upsert: true on a non-existing collection, the collection is implicitly created.从MongoDB 4.4开始,如果在不存在的集合上使用upsert:true运行更新或替换操作,则会隐式创建该集合。
In MongoDB 4.2 and earlier, if upsert: true, the operation must be run on an existing collection. 在MongoDB 4.2及更早版本中,如果upsert:true,则该操作必须在现有集合上运行。
Tip

See also: 另请参阅:

DDL OperationsDDL操作
db.collection.insertMany()
db.collection.insertOne()
insertStarting in MongoDB 4.4, if run on a non-existing collection, the collection is implicitly created.从MongoDB 4.4开始,如果在不存在的集合上运行,则会隐式创建该集合。
In MongoDB 4.2 and earlier, the operation must be run on an existing collection. 在MongoDB 4.2及更早版本中,操作必须在现有集合上运行。
Tip

See also: 另请参阅:

DDL OperationsDDL操作
db.collection.updateOne()
db.collection.updateMany()
db.collection.replaceOne()
updateStarting in MongoDB 4.4, if run on a non-existing collection, the collection is implicitly created.从MongoDB 4.4开始,如果在不存在的集合上运行,则会隐式创建该集合。
In MongoDB 4.2 and earlier, the operation must be run on an existing collection. 在MongoDB 4.2及更早版本中,操作必须在现有集合上运行。
Tip

See also: 另请参阅:

DDL OperationsDDL操作
db.collection.bulkWrite()
Various Bulk Operation Methods各种批量操作方法
Starting in MongoDB 4.4, if run on a non-existing collection, the collection is implicitly created.从MongoDB 4.4开始,如果在不存在的集合上运行,则会隐式创建该集合。
In MongoDB 4.2 and earlier, the operation must be run on an existing collection. 在MongoDB 4.2及更早版本中,操作必须在现有集合上运行。
Tip

See also: 另请参阅:

DDL OperationsDDL操作
Note

Updates to Shard Key Values分片键值的更新

Starting in MongoDB 4.2, you can update a document's shard key value (unless the shard key field is the immutable _id field) by issuing single-document update/findAndModify operations either in a transaction or as a retryable write. 从MongoDB 4.2开始,您可以通过在事务中或作为可重试写入发出单个文档update/findAndModify操作来更新文档的分片键值(除非分片键字段是不可变的_id字段)。For details, see Change a Document's Shard Key Value.有关详细信息,请参阅更改文档的分片键值

Count Operation计数操作

To perform a count operation within a transaction, use the $count aggregation stage or the $group (with a $sum expression) aggregation stage.要在事务中执行计数操作,请使用$count聚合阶段或$group(带有$sum表达式)聚合阶段。

MongoDB drivers compatible with the 4.0 features provide a collection-level API countDocuments(filter, options) as a helper method that uses the $group with a $sum expression to perform a count. The 4.0 drivers have deprecated the count() API.与4.0功能兼容的MongoDB驱动程序提供了一个集合级API countDocuments(filter, options)作为一个助手方法,使用带有$sum表达式的$group来执行计数。4.0驱动程序已弃用count()API。

Starting in MongoDB 4.0.3, mongosh provides the db.collection.countDocuments() helper method that uses the $group with a $sum expression to perform a count.从MongoDB 4.0.3开始,mongosh提供了db.collection.countDocuments()辅助方法,该方法使用带有$sum表达式的$group来执行计数。

Distinct Operation独特的操作

To perform a distinct operation within a transaction:要在事务中执行不同的操作:

  • For unsharded collections, you can use the db.collection.distinct() method/the distinct command as well as the aggregation pipeline with the $group stage.对于未排序的集合,可以使用db.collection.distinct()方法/distinct命令以及带有$group阶段的聚合管道。
  • For sharded collections, you cannot use the db.collection.distinct() method or the distinct command.对于分片集合,不能使用db.collection.distinct()方法或distinct命令。

    To find the distinct values for a sharded collection, use the aggregation pipeline with the $group stage instead. 要查找分片集合的不同值,请使用带有$group阶段的聚合管道。For example:例如:

    • Instead of db.coll.distinct("x"), use不使用db.coll.distinct("x"),而是使用

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

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

    The pipeline returns a cursor to a document:管道将游标返回到文档:

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

    Iterate the cursor to access the results document.迭代游标以访问结果文档。

DDL OperationsDDL操作

Starting in MongoDB 4.4 with feature compatibility version (fcv) "4.4", you can create collections and indexes inside a multi-document transaction if the transaction is not a cross-shard write transaction.功能兼容版本(fcv)“4.4”的MongoDB 4.4开始,如果事务不是跨分片写入事务,则可以在多文档事务中创建集合和索引。

Explicit DDL Operations显式DDL操作

Command命令Method方法Notes备注
createdb.createCollection()See also the Implicit DDL Operations.另请参阅隐式DDL操作
createIndexesdb.collection.createIndex()
db.collection.createIndexes()
The index to create must either be on a non-existing collection, in which case, the collection is created as part of the operation, or on a new empty collection created earlier in the same transaction.要创建的索引必须位于不存在的集合上(在这种情况下,集合是作为操作的一部分创建的),或者位于同一事务中先前创建的新的空集合上。
Note

For explicit creation of a collection or an index inside a transaction, the transaction read concern level must be "local".对于在事务内显式创建集合或索引,事务读取关注级别必须为"local"

For more information on creating collections and indexes in a transaction, see Create Collections and Indexes In a Transaction.有关在事务中创建集合和索引的详细信息,请参阅在事务中新建集合和索引

Implicit DDL Operations隐式DDL操作

You can also implicitly create a collection through the following write operations against a non-existing collection:您还可以通过对不存在的集合执行以下写操作来隐式创建集合:

Method Run against Non-Existing Collection方法对不存在的集合运行Command Run against Non-Existing Collection针对不存在的集合运行命令
db.collection.findAndModify() with upsert: true
db.collection.findOneAndReplace() with upsert: true
db.collection.findOneAndUpdate() with upsert: true
findAndModify with upsert: true
db.collection.insertMany()
db.collection.insertOne()
insert
db.collection.updateOne() with upsert: true
db.collection.updateMany() with upsert: true
db.collection.replaceOne() with upsert: true
update with upsert: true
db.collection.bulkWrite() with insert or upsert:true operations使用插入或upsert:true操作的db.collection.bulkWrite()
Various Bulk Operation Methods with insert or upsert:true operations使用插入或upsert:true操作的各种批量操作方法

For other CRUD operations allowed in transactions, see CRUD Operations.有关事务中允许的其他CRUD操作,请参阅CRUD操作

For more information on creating collections and indexes in a transaction, see Create Collections and Indexes In a Transaction.有关在事务中创建集合和索引的详细信息,请参阅在事务中新建集合和索引

Informational Operations信息操作

Informational commands, such as hello, buildInfo, connectionStatus (and their helper methods) are allowed in transactions; however, they cannot be the first operation in the transaction.事务中允许使用信息命令,如hellobuildInfoconnectionStatus(及其辅助方法);但是,它们不能是事务中的第一个操作。

Restricted Operations受限操作

Changed in version 4.44.4版更改.

The following operations are not allowed in transactions:事务记录中不允许执行以下操作: