Azure函数插入但不更新cosmosDB

时间:2019-02-26 14:35:22

标签: azure azure-functions azure-cosmosdb upsert

我有一个azure函数,用于从Azure服务总线队列接收消息并将文档发送到cosmosDB。我正在使用Azure函数1.x:

public static class Function1
{
    [FunctionName("Function1")]
    public static void Run([ServiceBusTrigger("ServiceBusQueue", AccessRights.Manage, Connection = "ServiceBusQueueConnection")]BrokeredMessage current, [DocumentDB(
            databaseName: "DBname",
            collectionName: "Colname",
            ConnectionStringSetting = "CosmosDBConnection")]out dynamic document, TraceWriter log)
    {
        document = current.GetBody<MyObject>(); 
        log.Info($"C# ServiceBus queue triggered function processed the message and sent to cosmos"); 
    }
}

这成功插入到了cosmos,但是更新时出现错误:

Microsoft.Azure.Documents.DocumentClintException: Entity with the specified id already exists in the system.

我要更新的键是该集合的分区键。

我看到了这个问题:Azure function C#: Create or replace document in cosmos db on HTTP request 但似乎我的用法类似于Matias Quarantas回答中的用法。他还提到使用out参数会导致宇宙上升。

如何在仍然使用天蓝色功能1.x的同时创建此“ upsert”功能?

1 个答案:

答案 0 :(得分:1)

该绑定确实会执行Upsert操作。

我创建了此示例函数,该函数采用Http有效负载(JSON),并将其按原样存储在Cosmos DB中:

[FunctionName("Function1")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req,
   [DocumentDB("MyDb", "MyCollection", ConnectionStringSetting = "MyCosmosConnectionString")] out dynamic document,
   TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");

    dynamic data = req.Content.ReadAsAsync<object>().GetAwaiter().GetResult();
    document = data;

    return req.CreateResponse(HttpStatusCode.OK);
}

如果我将JSON有效负载发送到Http端点,则输出绑定将按预期工作:

Sending payload with Postman

当我检查数据浏览器时,我看到:

Document in the Data Explorer

这次,如果我发送第二个有效负载,则添加一个属性(相同ID):

Sending updated payload through Postman

数据浏览器显示文档已更新,并且具有相同的功能代码:

Document updated in Data Explorer

您可以添加完整的异常/错误跟踪吗?您的服务总线消息中是否包含“ id”?您的收藏是否已分区?

如果您的集合已分区并且您正在更改Partition键属性的值,那么绑定将不会更新现有文档,它将创建一个新的文档,因为Upsert操作将找不到现有文档(基于在ID /分区键上)。但这不会引发异常。