【问题标题】:Handling duplicate data in Cosmos Db处理 Cosmos Db 中的重复数据
【发布时间】:2021-06-15 14:58:48
【问题描述】:

下面是我在 Cosmos Db 中添加 json 文档的代码。我的分区键是 TypeId,TypeId 和 CValue 的组合创建了一个唯一值。现在下面的代码能够在我的 cosmosDb 中添加文档,但它也允许添加重复的项目,我想避免这种情况并想知道我该如何处理?每当添加新文档时,它会检查具有相同唯一键(TypeId 和 CValue)的文档是否存在,如果存在,则覆盖或不添加它。

var content = JsonConvert.DeserializeObject<JObject>( lines );
var client = new DocumentClient( new Uri( DbInstance ),Key );
await client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(
                Database, Collection ),
                content);

content 是一个 JObject,这里是 content 的示例输出:

"Classes": {
    "Subjects": {
      "Name": "testA",
      "TypeId": "AS88QW",
      "Public": "No"
    },
    "Sections": {
      "Scopes": true,
      "CValue": [12,12,1]
    }
  }

【问题讨论】:

  • 您可以在创建容器时创建唯一键。你调查过吗?
  • 根据您之前的@​​987654321@,我假设您的容器的分区键是Classes/Subjects/TypeId。对吗?
  • 我查看了它,但没有这样的代码创建唯一键。你是对的关于分区键
  • 唯一键约束被定义为容器创建的一部分,即您在创建容器时定义唯一键约束。
  • 这里我需要两个键的组合作为唯一键

标签: c# azure-cosmosdb


【解决方案1】:

我按照大卫的想法进行了测试,但失败了,请允许我在下面展示我的测试结果以供后续讨论。

当我们创建容器时,我们可以设置唯一键,在你的情况下,你可以在字段中输入Classes/Subjects/TypeId,Classes/Sections/CValue

但根据我的测试,它不能对类型数组产生影响。把CValue 变成字符串怎么样?

==================更新=======================

创建合成密钥,参考this sdk

using Microsoft.Azure.Cosmos;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;

namespace ConsoleApp1
{
    class Program
    {
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            CosmosClient client = new CosmosClient("https://yourcosmosdb.documents.azure.com:443/", "cosmosdb_primary_key_here");
            Container container = await client.GetDatabase("database_name").DefineContainer(name: "container_name", partitionKeyPath: "/ptk")
                .WithUniqueKey()
                .Path("/combinedProperity_set_to_be_unique_key")
                .Attach()
                .CreateIfNotExistsAsync();

            var lines = "{\"id\":\"001\",\"TypeId\": \"AS88QW\",\"CValue\":[12,12,1]}";
            JObject content = JsonConvert.DeserializeObject<JObject>(lines);
            string TypeId = content.GetValue("TypeId").ToString();
            string CValue = content.GetValue("CValue").ToString();
            content.Add(new JProperty("combinedProperty", TypeId+"-"+ CValue));
            Console.WriteLine(content);
            ItemResponse<JObject> createResponse = await container.CreateItemAsync(content);
        }
    }
}

【讨论】:

  • 但是如何在我的代码中做到这一点?我不想改变 Cvalue 的类型,可以允许创建唯一键但不能改变 json 的初始结构
  • 创建容器时请注意unique key can only be created。而在.net SDK中,你可以关注this tutorial
  • 我们知道.. 我们面临的挑战是密钥是数组类型,并且不允许将此密钥用作唯一密钥。唯一键只支持字符串数字和布尔类型的键
  • 这个由数据库决定,我们可以尝试灵活的改变来满足你的要求,这就是你新创建的问题提到的,使用合成密钥,根据the doc,我们可以结合TypeIdCValue 的值类似于 AS88QW-[12,12,1],并将此属性设置为分区键。喜欢i.stack.imgur.com/PeEec.png
  • 没错..但我找不到任何实现该功能的代码示例
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多