对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

collMod(数据库命令)

collMod

collMod 可以让您向集合添加选项或修改视图定义。

提示

mongosh 中,该命令也可以通过 hideIndex()unhideIndex() 辅助函数运行。

辅助方法对 mongosh 用户来说很方便,但它们返回的信息级别可能与数据库命令不同。如果不追求方便或需要额外的返回字段,请使用数据库命令。

注意

collMod 修改的视图并非指的是物化视图。有关按需物化视图的讨论,请参阅 $merge

此命令可用于以下环境中托管的部署:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

注意

所有 MongoDB Atlas 集群都支持此命令。有关 Atlas 对所有命令的支持的信息,请参阅不支持的命令

该命令具有以下语法:

db.runCommand(
{
collMod: <collection or view>,
<option1>: <value1>,
<option2>: <value2>,
...
}
)

对于 <collection or view>,指定当前数据库中集合或视图的名称。

要更改索引选项,请指定想要更改的索引选项的现有键模式或名称:

db.runCommand( {
collMod: <collection>,
index: {
keyPattern: <index_spec> | name: <index_name>,
expireAfterSeconds: <number>, // Set the TTL expiration threshold
hidden: <boolean>, // Change index visibility in the query planner
prepareUnique: <boolean>, // Reject new duplicate index entries
unique: <boolean> // Convert an index to a unique index
},
dryRun: <boolean>
} )

如果索引不存在,该命令将出错并显示以下消息:"cannot find index <name|keyPattern> for ns <db.collection>"

index

index 选项可以更改现有索引的以下属性:

索引属性
说明

expireAfterSeconds

用于确定 TTL 集合过期阈值的秒数。

如果成功,该命令将返回一份包含以下内容的文档:

  • expireAfterSeconds_newexpireAfterSeconds

  • expireAfterSeconds_oldexpireAfterSeconds 的旧值(如果索引之前设置了expireAfterSeconds 的值)。

修改索引选项 expireAfterSeconds 会重置该索引的 $indexStats

如果您使用 MongoDB 5.0 之前版本创建的 TTL 索引,或者要将 MongDB 5.0 创建的数据与之前版本同步,请参阅使用 NaN 配置索引,以避免错误配置问题。

TTL 索引 expireAfterSeconds 值必须介于 02147483647(包含两者)之间。

hidden

确定索引是否对查询计划器隐藏的布尔值。

如果 hidden 值发生更改,该命令将返回一个文档,其中包含已更改属性的旧值和新值:hidden_oldhidden_new

但是,如果 hidden 值没有变化(即隐藏已隐藏的索引或取消隐藏已取消隐藏的索引),该命令会从输出中忽略 hidden_oldhidden_new 字段。

要隐藏索引,必须将 featureCompatibilityVersion 设置为 4.4 或更大。

如果该值发生变化,修改索引选项 hidden 会重置索引的 $indexStats

prepareUnique

一个布尔值,用于确定索引是否接受新的重复条目。

prepareUniquetrue 时,新的重复条目会失败并出现 DuplicateKey 错误。由此产生的索引可转换为唯一索引。要转换索引,使用 collModunique 选项。

如果更新现有索引使得 prepareUniquetrue,则不会检查该索引是否存在预先存在的重复索引条目。

6.0版本新增。:

unique

确定索引是否唯一的布尔值。

不支持 false 的值。

uniquetrue 时,collMod 会扫描 keyPattern 索引有无重复项,如果没有重复索引条目,则将其转换为唯一索引。

如果在初始扫描期间检测到重复条目,collMod 将返回 CannotConvertIndexToUnique 和冲突文档列表。要将具有重复条目的索引转换为唯一索引,请更正所有报告的冲突并重新运行 collMod

要结束转换,请将 prepareUnique 设置为 false

要查看如何将非唯一索引转换为唯一索引的示例,请参阅将现有索引转换为唯一索引

6.0版本新增。:

dryRun

默认值: false

仅在 index.uniquetrue 时使用。

在将非唯一索引转换为唯一索引之前,可以使用 dryRun: true运行 collMod 命令。如果这样做,MongoDB 会检查集合中是否存在重复的密钥,并返回任何冲突。

使用 dryRun: true,以确认您可以将索引转换为唯一索引而不会出现任何错误。

validator

validator 允许用户为集合指定验证规则或表达式

validator 选项采用指定验证规则或表达式的文档。可以使用与该查询运算符相同的操作符来指定表达式,但 $near$nearSphere$text$where 除外。

注意

  • 更新和插入期间进行验证。现有文档在修改之前不会进行验证检查。

  • 不能为 adminlocalconfig 数据库中的集合指定验证器。

  • 无法为 system.* 集合指定验证器。

validationLevel

validationLevel 确定 MongoDB 在更新期间将验证规则应用于现有文档的严格程度。

"off"

不对插入或更新进行验证。

"strict"

默认将验证规则应用于所有插入和所有更新。

"moderate"

将验证规则应用于现有有效文档的插入和更新。请勿将规则应用于现有无效文档的更新。

要查看使用 validationLevel 的示例,请参阅为现有文档指定验证级别。

validationAction

validationAction 选项确定是否对无效文档进行 error,或者仅 warn 违反但允许无效文档。

重要

文档验证仅适用于由 validationLevel 确定的文档。

要查看使用 validationAction 的示例,请参阅选择如何处理无效文档

注意

此命令修改的视图并非指的是物化视图。有关按需物化视图的讨论,请参阅 $merge

viewOn

底层源集合或视图。视图定义是通过将指定的 pipeline 应用于此源来确定的。

如果在运行访问控制的 MongoDB 部署上修改视图,则需使用此命令。

pipeline

定义视图聚合管道

注意

视图定义 pipeline 不能包含 $out$merge 阶段。这一限制也适用于嵌入式管道,例如在 $lookup$facet 阶段中使用的管道。

如果在运行访问控制的 MongoDB 部署上修改视图,则需使用此命令。

视图定义是公开的;即视图上的 db.getCollectionInfos()explain 操作将包括定义视图的管道。因此,应避免在视图定义中直接引用敏感字段和值。

db.runCommand( {
collMod: "myView",
viewOn: "activities",
pipeline: [
{ $match: { status: "Q" } },
{ $project: { user: 1, date: 1, description: 1} } ]
} )

注意

如果在 collMod 操作的 timeseries 参数中指定修改,则无法在同一命令中使用其他修改选项。您必须使用与其他集合修改分开的专用命令来执行时间序列修改。

expireAfterSeconds

注意

这不同于使用带有 expireAfterSeconds 属性的 index 选项来更改 TTL 集合的过期时间。

要启用自动删除文档或修改时间序列集合的当前过期时间间隔,请更改 expireAfterSeconds 值:

db.runCommand( {
collMod: <collection>,
expireAfterSeconds: <number> | "off"
} )

expireAfterSeconds 设定为 "off" 可禁用自动删除,或设定为非负十进制数 (>=0) 以指定文档过期的秒数。

granularity

要修改时间序列集合的粒度,可以将 timeseries.granularity 从较短的时间单位增加到较长的时间单位:

db.runCommand( {
collMod: "weather24h",
timeseries: { granularity: "seconds" | "minutes" | "hours" }
} )

要更新自定义分桶字段bucketRoundingSecondsbucketMaxSpanSeconds而不是granularity ,请将这两个自定义字段包含在collMod命令中并将它们设置为相同的值:

db.runCommand( {
collMod: "weather24h",
timeseries: {
bucketRoundingSeconds: 86400,
bucketMaxSpanSeconds: 86400
}
} )

您无法减少粒度间隔或自定义分桶值。

重要

如果任何time-series collection明确指定了自定义分桶字段bucketMaxSpanSecondsbucketRoundingSeconds ,则无法降级到 MongoDB 6.3 以下。如果可能,请转换为相应的granularity 。 如果不能,则必须在降级之前删除该collection。

要将集合从自定义分桶转换为 granularitybucketMaxSpanSecondsbucketRoundingSeconds 值都必须小于或等于 granularity 等效值:

granularity
bucketRoundingSeconds 限值(包含本数)
bucketMaxSpanSeconds 限值(包含本数)

seconds

60

3600

minutes

3600

86400

hours

86400

2592000

6.0版本新增。:

从 MongoDB 6.0 开始,您可以重新调整固定大小集合。要更改固定大小集合的最大字节数,请使用 cappedSize 选项。要更改现有固定大小集合中的最大文档数,请使用 cappedMax 选项。

注意

您不能使用这些命令来调整 oplog 的大小。请改用 replSetResizeOplog

cappedSize

指定固定大小集合新的最大大小(以字节为单位)。cappedSize 必须大于 0 且小于 1e+15 (1 PB)。

cappedMax

指定固定大小集合中新的最大文档数。将 cappedMax 设置为小于或等于 0 意味着没有限制。

例如,以下命令将固定大小集合的大小上限设置为 100000 字节,并将集合中的最大文档数设置为 500:

db.runCommand( {
collMod: <collection>,
cappedSize: 100000,
cappedMax: 500
} )

6.0版本新增。:

changeStreamPreAndPostImages

从 MongoDB 6.0 开始,可使用变更流事件来输出更改前后的文档版本(文档前映像和后映像):

  • 前映像是指被替换、更新或删除之前的文档。已插入的文档没有前映像。

  • 后图像是插入、替换或更新后的文档。 已删除的文档没有后图像。

  • 使用 db.createCollection()createcollMod 为集合启用 changeStreamPreAndPostImages。示例,使用 collMod 命令时:

    db.runCommand( {
    collMod: <collection>,
    changeStreamPreAndPostImages: { enabled: true }
    } )

要使用 collMod 启用集合的 change stream 前图像和后图像,请使用 changeStreamPreAndPostImages 字段:

db.runCommand( {
collMod: <collection>,
changeStreamPreAndPostImages: { enabled: <boolean> }
} )

要启用集合的变更流前图像和后图像,请将 changeStreamPreAndPostImages 设定为 true。例如:

db.runCommand( {
collMod: "orders",
changeStreamPreAndPostImages: { enabled: true }
} )

要禁用集合的变更流前后映像,请将 changeStreamPreAndPostImages 设为 false。例如:

db.runCommand( {
collMod: "orders",
changeStreamPreAndPostImages: { enabled: false }
} )

如果图像属于以下情况,则前像和后像不可用于变更流事件

  • 在文档更新或删除操作时未对集合启用。

  • expireAfterSeconds 中设置的前像和后像保留时间后之后被删除。

    • 以下示例将整个集群上的 expireAfterSeconds 设置为 100 秒:

      use admin
      db.runCommand( {
      setClusterParameter:
      { changeStreamOptions: {
      preAndPostImages: { expireAfterSeconds: 100 }
      } }
      } )

      注意

      MongoDB Atlas集群中不支持setClusterParameter命令。有关AtlasAtlas支持所有命令的信息,请参阅AtlasAtlas中不支持的命令。

    • 以下示例返回当前的 changeStreamOptions 设置,包括 expireAfterSeconds

      db.adminCommand( { getClusterParameter: "changeStreamOptions" } )
    • expireAfterSeconds 设置为 off 可使用默认保留策略:将保留前像和后像,直到从 oplog 中删除对应的变更流事件。

    • 如果变更流事件从 oplog 中删除,则无论 expireAfterSeconds 前映像和后映像保留时间如何,相应的前映像和后映像也会被删除。

其他考量:

  • 启用前像和后像会占用存储空间并增加处理时间。仅在需要时启用前像和后像。

  • 将变更流事件大小限制为小于 16 MiB。要限制事件大小,您可以:

    • 将文档大小限制为 8 MB。如果其他 change stream 事件字段(例如 updateDescription)不是很大,则可以在 change stream 输出中同时请求更新前的文档和更新后的文档。

    • 如果其他变更流事件字段(例如 updateDescription)并不大,则仅请求变更流输出中最多 16 MiB 的文档的后像。

    • 在以下情况下,仅请求变更流输出中最多 16 MiB 的文档的前像:

      • 文档更新仅影响文档结构或内容的一小部分,

      • 不会引起 replace 变更事件。replace 事件始终包含后像。

  • 要请求前图像,请在db.collection.watch()中将fullDocumentBeforeChange设置为requiredwhenAvailable。要请求后图像,您可以使用相同的方法设置fullDocument

  • 前像被写入 config.system.preimages 集合。

    • config.system.preimages 集合可能会变大。要限制集合大小,可如前文所示为前映像设置 expireAfterSeconds 时间。

    • 要监控 config.system.preimages 的大小,请连接到分片集群上的分片节点或副本集上的 mongod 节点。然后,运行以下命令:

      use config
      db.system.preimages.totalSize()
      db.system.preimages.stats()

      注意

      您必须对 config.system.preimages 集合拥有 collStats 权限操作才能运行这些命令。

      要在 MongoDB Atlas 部署上运行这些命令,您必须具有 atlasAdmin 角色。

    • 前像由后台进程异步删除。

重要

向后不兼容的功能

从 MongoDB 6.0 开始,如果您为变更流使用文档前像和后像,则必须使用 collMod 命令为每个集合禁用 changeStreamPreAndPostImages,然后才能降级到更早版本的 MongoDB。

提示

comment

可选。您可以为该命令附加注释。评论必须是顶层字段,可以是任何有效的 BSON 类型。您指定的注释会与该命令的记录一起出现在以下位置:

w

可选。一份表达 collMod 命令的写关注文档。

省略以使用默认的写关注。

如果部署强制执行身份验证/授权,您必须具有以下特权才能运行 collMod 命令:

任务
所需权限

修改非固定大小集合

collMod 在数据库中

修改视图

collMod 在数据库中以及:

  • 要修改的视图上无 find

  • 针对该视图的 find,从而对源集合/视图执行修改和 find

内置角色dbAdmin提供所需的特权。

collMod 命令在操作期间获取指定集合的集合锁。

以下示例更新 user_log 集合上现有 TTL 索引 { lastAccess: 1 }expireAfterSeconds 属性。该索引当前的 expireAfterSeconds 属性设置为 1800 秒(或 30 分钟),示例将该值更改为 3600秒(或 60 分钟)。

db.runCommand({
collMod: "user_log",
index: {
keyPattern: { lastAccess: 1 },
expireAfterSeconds: 3600
}
})

如果成功,该操作将返回一个文档,其中包含已更改属性的旧值和新值:

{ "expireAfterSeconds_old" : 1800, "expireAfterSeconds_new" : 3600, "ok" : 1 }

注意

要隐藏索引,必须将 featureCompatibilityVersion 设置为 5.0 或更大。

下面的示例隐藏了 orders 集合上的现有索引。具体而言,该操作会从查询规划器中隐藏具有规范 { shippedDate: 1 } 的索引。

db.runCommand( {
collMod: "orders",
index: {
keyPattern: { shippedDate: 1 },
hidden: true
}
} )

如果成功,该操作将返回一个文档,其中包含已更改属性的旧值和新值:

{ "hidden_old" : false, "hidden_new" : true, "ok" : 1 }

注意

如果操作成功但 hidden 值未更改(具体来说,隐藏已隐藏的索引或取消隐藏已取消隐藏的索引),则该命令会从输出中忽略 hidden_oldhidden_new字段。

要隐藏文本索引,您必须通过 name 而非通过 keyPattern 指定该索引。