如何在 Cosmos DB for MongoDB 中可靠地创建唯一索引?

问题描述 投票:0回答:1

我在 Cosmos DB for MongoDB 中创建唯一索引时遇到问题。适用于 MongoDB 的命令有时适用于 Cosmos DB for MongoDB,但有时会导致错误。我如何知道何时允许我创建唯一索引?我想知道而不是盲目尝试并等待错误消息出现。

我正在尝试向其中已有文档的现有集合添加唯一索引。以下是一些执行此操作的 mongosh 命令:

db.createCollection("testCollection")
db.testCollection.insertOne({someField: "value"})
db.testCollection.createIndex({someField: 1}, {unique: true})

上述命令在 MongoDB 和 Cosmos DB for MongoDB (vCore) 上成功。但是,在 Cosmos DB for MongoDB (RU) 上,最终命令会导致以下错误消息:

当集合包含文档时无法创建唯一索引

我的下一个尝试是创建一个新集合并首先创建唯一索引,然后再将任何文档添加到集合中。以下是一些执行此操作的 mongosh 命令:

db.createCollection("anotherCollection")
db.anotherCollection.createIndex({someField: 1}, {unique: true})

上述命令在 MongoDB、CosmosDB for MongoDB (vCore) 和定期备份的 Cosmos DB for MongoDB (RU) 上成功。但是,在具有连续备份(时间点还原)的 Cosmos DB for MongoDB (RU) 上,最终命令会导致以下错误消息:

Error=13,Details='响应状态码不表示成功:Forbidden (403);子状态:0;活动 ID: ;原因:(消息:{“错误”:[“无法修改唯一索引。要更改唯一索引,请删除集合并重新创建一个新集合。”]}

azure azure-cosmosdb mongo-shell azure-cosmosdb-mongoapi azure-cosmosdb-mongovcore
1个回答
0
投票

我最终发现微软的Azure文档证实了问题中描述的行为。

唯一密钥页面显示:

要为现有容器设置唯一密钥,请创建一个新容器 具有唯一键约束。使用适当的数据迁移 用于将数据从现有容器移动到新容器的工具 容器。

连续备份页面显示:

具有连续备份功能的 Azure Cosmos DB for MongoDB 帐户不会 支持为现有集合创建唯一索引。对于这样 一个帐户,必须与其一起创建唯一索引 收藏;这是使用创建集合扩展来完成的 命令。

总而言之,如果您想在已包含文档的集合上创建唯一索引,您的选择会受到限制,具体取决于您运行的 CosmosDB 变体:

具有连续备份(时间点恢复)功能的 Cosmos DB for MongoDB (RU)
使用CreateCollection扩展命令同时创建新集合和唯一索引。然后将现有文档复制到新集合中。例如:

db.runCommand({customAction: "CreateCollection", collection: "anotherCollection", indexes: [{key: {someField: 1}, name: "someField_1", unique: true}]})

注意:如果您使用 mongorestore 将现有文档复制到新集合,则当它尝试创建唯一索引时,如果它们与您手动创建的索引不完全匹配,您可能会收到错误。如果您已经创建了所有(唯一和非唯一)索引,您可以考虑使用

--noIndexRestore
选项。

具有定期备份功能的 Cosmos DB for MongoDB (RU)
使用前面的方法,或者您可以创建一个新集合,然后使用普通的 MongoDB createIndex 命令 创建唯一索引。然后将现有文档复制到新集合中。例如:

db.createCollection("anotherCollection")
db.anotherCollection.createIndex({someField: 1}, {unique: true})

适用于 MongoDB 的 Cosmos DB(vCore)
我使用 MongoDB 6.0 界面进行了一些测试,看来您可以使用普通的 MongoDB createIndex 命令 来创建唯一索引,即使集合中有文档也是如此。

db.testCollection.createIndex({someField: 1}, {unique: true})
© www.soinside.com 2019 - 2024. All rights reserved.