Azure Cosmos DB:使用 UpsertDocumentAsync 违反唯一索引约束

Posted

技术标签:

【中文标题】Azure Cosmos DB:使用 UpsertDocumentAsync 违反唯一索引约束【英文标题】:Azure Cosmos DB: Unique index constraint violation using UpsertDocumentAsync 【发布时间】:2022-01-06 18:01:12 【问题描述】:

我在 Azure Cosmos DB 容器中为字段 UniqueName 定义了一个 UniqueKey 策略

下面的函数正在定时器上调用。

我正在尝试使用 Azure Functions 绑定在 Azure Cosmos DB 中更新文档,如下所示:

public async Task ManageItems([ActivityTrigger] string records,
        [CosmosDB(
        databaseName: "mydatabase",
        collectionName: "items",
        ConnectionStringSetting = "CosmosDbConnectionString")] DocumentClient client,
        ILogger log)
        
             var collectionUri = UriFactory.CreateDocumentCollectionUri("mydatabase", "items");


            
            foreach (var record in records)
            
                log.LogDebug($"Upserting itemNumber=record.UniqueName");
                await client.UpsertDocumentAsync(collectionUri, record);
            
         

在空白“项目”容器中的第一次执行期间,每条记录的 Upsert 工作出色,将每条记录作为特定文档插入。

但是,在对与第一次执行相同的数据进行测试时,但现在期待“更新”而不是“插入”尝试,我得到一个异常:

UpsertDocumentAsync 方法运行后

违反唯一索引约束

我在这里错过了什么?

据我了解,Upsert 是更新或插入,取决于对象是否存在,通过它的唯一标识符。

检查来自方法的传出对象唯一 ID 是否与现有文档唯一 ID 匹配应该在 Cosmos DB 容器级别进行。

我期望发生的是调用通知具有该唯一 ID 的文档已经存在,并且它执行更新,而不是抛出异常。如果方法是仅插入,我希望它会抛出异常。

【问题讨论】:

【参考方案1】:

通过在“记录”来自的类中指定显式 "id" 字段来解决此问题。

"id" 设置为我想用作唯一值的唯一“recordNumber”。

为了更好地衡量,我在 UpsertDocumentAsync 方法中将 disableAutomaticIdGeneration 设置为 true

UpsertDocumentAsync(collectionUri, record, disableAutomaticIdGeneration:true);

不再有唯一索引违规,也没有重复。

值得注意的解决方案与此类似:How can I insert/update data in CosmosDB in an Azure function

【讨论】:

以上是关于Azure Cosmos DB:使用 UpsertDocumentAsync 违反唯一索引约束的主要内容,如果未能解决你的问题,请参考以下文章

Azure 数据工厂和 Cosmos DB

Azure上找不到MongoDB?不妨试试Azure Cosmos DB

是否可以使用 Java SDK 通过反向代理连接到 Azure Cosmos DB?

Azure Cosmos DB:使用 UpsertDocumentAsync 违反唯一索引约束

sql Azure Cosmos DB

如何使用 azure 流分析将 cosmos db 中的值更新为输出?