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

将现有索引转换为唯一索引

要将非唯一索引转换为唯一索引,请使用collMod命令。 collMod命令提供了一些选项,用于在完成转换之前验证索引字段是否包含唯一值。

collMod 命令转换现有索引。 MongoDB会扫描索引是否存在重复键,然后将该索引标记为唯一。

转换索引时,请记住以下行为:

  • 在转换索引之前,将 prepareUnique 设置为 true。如果 prepareUnique 为 false,则带有 unique: true 的 collMod 会返回错误。

  • 在单独的 collMod 命令中运行 prepareUnique 修改。不能将 prepareUnique 与其他索引修改结合使用。

  • 您无法在时间序列集合中的索引上设立prepareUnique。 MongoDB返回错误。

  • 如果在 collMod 转换索引时另一个操作修改或删除了该索引,则该命令将失败。其他操作完成后重新运行该命令。

对于分片的集合,以下行为也适用:

  • 如果任何分片包含重复键,则 collMod 将返回 CannotConvertIndexToUnique。 MongoDB不会转换任何分片上的索引。

  • 如果索引键与分片键冲突,则设置 prepareUnique 会失败。要学习;了解哪些索引在分片的集合上可以是唯一的,请参阅分片集群和唯一索引。

1

创建 apples 集合:

db.apples.insertMany( [ { type: "Delicious", quantity: 12 }, { type: "Macintosh", quantity: 13 }, { type: "Delicious", quantity: 13 }, { type: "Fuji", quantity: 15 }, { type: "Washington", quantity: 10 }] )
2

在 type 字段上添加单个字段索引:

db.apples.createIndex( { type: 1 } )
1

在 type 字段索引上运行 collMod 并将 prepareUnique 设置为 true:

db.runCommand( { collMod: "apples", index: { keyPattern: { type: 1 }, prepareUnique: true }} )

设置 prepareUnique 后,您将无法插入与索引键条目重复的新文档。例如,以下插入操作会导致错误:

db.apples.insertOne( { type: "Delicious", quantity: 20 } )
MongoServerError: E11000 duplicate key error collection:test.apples index: type_1 dup key: { type: "Delicious" }
2

要查看是否有任何文档违反了 type 字段的唯一约束,请使用 unique: true 和 dryRun: true 运行 collMod:

db.runCommand( { collMod: "apples", index: { keyPattern: { type: 1 }, unique: true }, dryRun: true} )
MongoServerError: Cannot convert the index to unique. Please resolve conflicting documents before running collMod again. Violations: [ { ids: [ ObjectId("660489d24cabd75abebadbd0"), ObjectId("660489d24cabd75abebadbd2") ] }]

注意

如果包含所有冲突的文档 _id 值的响应超过 8MB,MongoDB 将返回以下错误消息,而不是列出具体的违规:

Cannot convert the index to unique. Too many conflicting documentswere detected. Please resolve them and rerun collMod.

在这种情况下,解决重复条目,直到响应小于 8MB,然后再次运行 collMod,以查看剩余的违规条目。

3

要完成转换,请修改重复条目以消除任何冲突。例如:

db.apples.deleteOne( { _id: ObjectId("660489d24cabd75abebadbd2") })
4

要确认可以转换索引,请使用 dryRun: true 重新运行 collMod() 命令:

db.runCommand( { collMod: "apples", index: { keyPattern: { type: 1 }, unique: true }, dryRun: true} )
{ ok: 1 }
5

如要完成到唯一索引的转换,请运行 unique: true 的 collMod 命令并删除 dryRun 标记:

db.runCommand( { collMod: "apples", index: { keyPattern: { type: 1 }, unique: true }} )
{ unique_new: true, ok: 1 }