【问题标题】:Cosmos DB Upsert FailureCosmos DB Upsert 失败
【发布时间】:2020-09-24 13:34:25
【问题描述】:

尝试在使用 C# 的 Windows 10 上从 .NET Core 3.1 控制台应用将项目更新插入 Cosmos DB。

JSON 文档如下所示:

{
        "id": "25217f96-d399-4bb7-b8f1-4a7365cca76c",
        "title": "my title",
        "eventUtc": "2020-09-04T14:16:04+0000" ,
        "listOne":
                        [
                                {"person1" : "james" , "contributorContact" : "" , "contributorTtype" : "contributor"} ,
                                {"person2" : "veena" , "contributorContact" : "" , "contributorTtype" : "contributor"}
                        ]
        ,
        "listTwo" :
                        [
                                "lorem" , "ipsum"  , "dolor" 
                        ] ,
        "synopsis" : "abcdefghi."  }

该文档在容器中不存在,但该容器已与另一个文档一起存在。分区键是“id”。

此代码失败: ...

foreach (var fileOne in Directory.GetFiles(fileLoc))
{
    MemoryStream stream = new MemoryStream();
    await System.Text.Json.JsonSerializer.SerializeAsync(stream, File.ReadAllText(fileOne));
    var response = await cosmosContainer.UpsertItemStreamAsync(stream, new PartitionKey("id"));
}

文件不多,因此需要单独更新它们。

错误信息是:

响应状态码不表示成功:BadRequest(400); 子状态:0;活动ID:9c545c05-102f-4ed5-9c6c-e5092ae1671b; 原因:(消息:{“错误”:[“指定的输入之一是 无效"]}....

代码中的错误在哪里?基于https://github.com/Azure/azure-cosmos-dotnet-v3/issues/1463,我认为这可行。

谢谢。

【问题讨论】:

    标签: .net-core azure-cosmosdb azure-cosmosdb-sqlapi


    【解决方案1】:

    在您提供的代码中,您发送的似乎是分区键名称“id”而不是项目的id。它应该看起来像:

    foreach (var fileOne in Directory.GetFiles(fileLoc))
    {
        MemoryStream stream = new MemoryStream();
        await System.Text.Json.JsonSerializer.SerializeAsync(stream, File.ReadAllText(fileOne));
        string itemId = // Extract ID from item
        var response = await cosmosContainer.UpsertItemStreamAsync(stream, new PartitionKey(itemId));
    }
    

    注意在提供分区键时使用解析的itemId。此外,您可能希望在 MemoryStream 实例中使用 using 语句。

    【讨论】:

    • 此代码返回错误 "BadRequest (400); Substatus: 0; (Message: {"Errors":["指定的输入之一无效"]}" var itemId = "25217f96-d399 -4bb7-b8f1-4a7365cca76c"; 使用 (var memoryStream = new MemoryStream() ) { await JsonSerializer.SerializeAsync( memoryStream, File.ReadAllText(fileOne)); memoryStream.Seek(0, SeekOrigin.Begin); var response = await cosmosContainer .UpsertItemStreamAsync( memoryStream , new PartitionKey(itemId)); }
    • 我会怀疑原始数据并首先将其反序列化为一个类型化的对象,然后再将其用作要更新的项目。这样你就可以检查它是否被正确读取。
    • 我创建了一个 Type 并用 Newtonsoft Attributes 装饰它并使用了 Newtonsoft 反序列化器,然后项目插入正常。我希望为了速度,不需要将文件转换为字符串到对象以进行插入,因为如果我访问 Azure 门户并复制粘贴文档的文本,它就可以很好地插入。那好吧。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多