【问题标题】:Partition Key for Cosmos DBCosmos DB 的分区键
【发布时间】:2018-02-26 20:31:45
【问题描述】:

我正在使用 ASP.NET Core 和 Cosmos DB 构建一个宁静的 API。有一个需要分区键的 GetItemById 请求。

 public static async Task<T> GetItemAsync(string itemId, string name)
    {
        try
        {
            Document document =
                await client.ReadDocumentAsync(UriFactory.CreateDocumentUri(DatabaseId, CollectionId, itemId),
                    new RequestOptions() { PartitionKey = new PartitionKey(name) });

            return (T)(dynamic)document;
        }
        catch (DocumentClientException e)
        {
            if (e.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                return null;
            }
            else
            {
                throw;
            }
        }
    }

GetByIdAsync() 函数调用此 GetItemAsync() 方法。

    [HttpGet("{itemId}")]
    public async Task<IActionResult> GetByIdAsync(string itemId, string name)
    {
        var item = await DocumentDBRepository<TodoItem>.GetItemAsync(itemId, name);
        if (item == null)
        {
            return NotFound();
        }
        return new ObjectResult(item);
    }

网址是http://localhost:54084/api/todo/f323307b-142f-46f3-9072-12f41cc74e87

我的 Azure CosmosDB 容器如下所示:

但是当我运行它时,它给了我一个错误

{Microsoft.Azure.Documents.DocumentClientException:分区键 提供不符合集合中的定义或 与文档中指定的分区键字段值不匹配。

【问题讨论】:

  • 你为“name”传递了什么值?集合的分区键定义是什么?
  • @AravindKrishnaR。这是我感到困惑的部分。对于您的第一个问题,我刚刚为“名称”传入了 null。对于您的第二个问题,我不确定我们为什么需要分区键。我在想如果我们需要通过它的 id 来获取一个项目,我们只需要它的 id。这就是为什么我认为它只需要 URL 的 id。为什么我们需要它的名字?
  • @AravindKrishnaR。我还在上面添加了分区键定义的屏幕截图。谢谢!
  • 在 Cosmos DB 中,主键是分区键和行键(“id”)的组合。两者的组合唯一地标识一行 - 而不是单独的“id”。所以需要在分区键中指定Name的值才能找到项目(不为空)。如果您的应用没有自然 PK,那么您应该考虑将“/id”设置为分区键(并传递 id 和分区键的值)
  • 从截图来看,您的收藏似乎没有分区键。

标签: api azure asp.net-core azure-cosmosdb database-partitioning


【解决方案1】:

在 Cosmos DB 中,主键是分区键和行键(“id”)的组合。两者的组合唯一标识一行 - 而不是单独的“id”。所以需要在partition key中指定Name的值才能找到item(不为null)。

如果您的应用没有自然 PK,那么您应该考虑将“/id”设置为分区键(并传递 id 和分区键的值)

【讨论】:

    【解决方案2】:

    我想通了。我收到此错误的原因是因为我的集合中没有设置分区键。这就是为什么我应该删除

    new RequestOptions() { PartitionKey = new PartitionKey(name) }

    我删除它后,它可以正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多