azure x-ms-partitionkey标头中提供的分区键的组件比集合中定义的少

szqfcxe2  于 2023-11-21  发布在  其他
关注(0)|答案(1)|浏览(136)

我尝试使用PowerShell向Azure中的Cosmos DB API发送请求,但我不断从服务返回以下错误:
“x-ms-partitionkey标头中提供的分区键的组件少于集合中定义的组件。”
当我使用x-ms-documentdb-partitionkey头时也是如此,无论我尝试GET(读取)请求,还是尝试POST/PUT(创建/更新)文档,都会发生这种情况。如果我尝试发送空数组的值,或者带有单个空字符串的数组,或者枚举“None”,我都会得到一条错误消息“分区键None无效”(或者我给出的任何值)。
但是,我的集合是在需要分区键之前创建的,所以我的集合最初没有分区键。在迁移数据库之后,集合设置选项卡显示“分区键”值/_partitionKey,启用了大分区键。还有一个注意,容器是非分层分区的。但是,我的文档都没有属性“_partitionKey”,一个都没有价值
如何使用原生PowerShell处理Cosmos API?

njthzxwz

njthzxwz1#

经过大量的搜索和尝试/错误,我终于能够得到一些工作。随意使用这个为您自己的PowerShell需要。

认证

首先,您需要进行身份验证。您可以硬编码访问密钥,也可以使用以下命令动态检索它。

  1. $keys = Invoke-AzResourceAction -Action "listkeys" `
  2. -ResourceType "Microsoft.DocumentDb/databaseAccounts" `
  3. -ResourceGroupName $rgName `
  4. -Name $cosmosAccountName `
  5. -ApiVersion "2015-04-08" `
  6. -Force
  7. $keys.primaryMasterKey # Use this one for writing.
  8. $keys.primaryReadonlyMasterKey # Use this one for reading.

字符串
你需要获取这个密钥,并生成一个认证头。但是要做到这一点,你需要知道你将对哪个URL发出请求,以及什么动词(例如POST,PUT等)。
如果您正在执行查询,则您的ResourceLink将是集合文档(例如dbs/myDatabase/colls/myCollection/docs)。如果您正在创建或更改文档,则您的ResourceLink将是特定文档(例如dbs/myDatabase/colls/myCollection/docs/myDocGUID)。在这两个示例中,您的ResourceType将是docs

  1. # Credit from this URL: https://sql-articles.com/articles/azure/cosmos-db/provisioning-azure-cosmos-db-using-powershell/
  2. function Generate-MasterKeyAuthorizationSignature {
  3. [CmdletBinding()]
  4. [OutputType([string])]
  5. Param (
  6. # The HTTP verb going to be used with this authorization signature. Can choose from 'DELETE', 'GET', 'PATCH', 'POST', or 'PUT'.
  7. [Parameter(Mandatory)]
  8. [ValidateSet("DELETE", "GET", "PATCH", "POST", "PUT")]
  9. [string] $Verb,
  10. # The access key to use for authentication to the target.
  11. [Parameter(Mandatory)]
  12. [string] $Key,
  13. # Optional Parameter. The link of the resource we are requesting access to (e.g. dbs/myDatabase/colls/myCollection/docs/myDocID).
  14. [Parameter()]
  15. [string] $ResourceLink = [string]::Empty,
  16. # Optional Parameter. The type of resource we are requesting access to (e.g. docs).
  17. [Parameter()]
  18. [string] $ResourceType = [string]::Empty,
  19. # Optional Parameter. The date and time to attach to this signature. Default value is right now, UTC.
  20. [Parameter()]
  21. [string] $DateTime = ([DateTime]::UtcNow.ToString("r")),
  22. # Optional Parameter. The type of key the Key value represents. Default value is 'master'.
  23. [Parameter()]
  24. [string] $KeyType = "master",
  25. # Optional Parameter. The algorithm version that was used to generate the key (e.g. 1.0). Default value is '1.0'.
  26. [Parameter()]
  27. [string] $TokenVersion = "1.0"
  28. )
  29. Process {
  30. $hmacSha256 = New-Object System.Security.Cryptography.HMACSHA256
  31. $hmacSha256.Key = [System.Convert]::FromBase64String($Key)
  32. if ($ResourceLink -eq $ResourceType) {
  33. $ResourceLink = [string]::Empty
  34. }
  35. $payload = "$($Verb.ToLowerInvariant())`n$($ResourceType.ToLowerInvariant())`n$ResourceLink`n$($DateTime.ToLowerInvariant())`n`n"
  36. $hashPayload = $hmacSha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($payload))
  37. $signature = [System.Convert]::ToBase64String($hashPayload)
  38. return [System.Web.HttpUtility]::UrlEncode("type=$KeyType&ver=$TokenVersion&sig=$signature")
  39. }
  40. }


如果声明并调用上面的函数,您将获得authorization头所需的值。

头部

  1. $headers = @{
  2. authorization = $authSig
  3. "x-ms-date" = $dateTime
  4. "x-ms-version" = "2020-07-15"
  5. "x-ms-max-item-count" = 100
  6. } # Shared headers used by all requests.


如果您正在查询数据,则需要以下标题(除了上面的标题之外):

如果您正在更改数据,您将需要以下标题(除了共享):

  • x-ms-documentdb-partitionkey: []您的内容类型将为application/json。如果您不使用分区,或从无分区集合迁移,请将空数组[]设置为您的分区键。否则,给予一个数组,其中包含单个字符串和您的分区键(目前他们只支持一次使用一个)。

Body

如果你正在查询数据,你的主体将是一个包含查询的JSON主体。如果需要,你也可以使用参数,作为一个单独的JSON属性。

  1. $body = @{
  2. query = "select * from C"
  3. }


如果您正在更改数据,您的主体将是整个文档(在创建或替换时)或patch operation

  1. $body = @{
  2. operations = @(
  3. @{
  4. op = "replace"
  5. path = "/myJsonPath"
  6. value = "blah"
  7. }
  8. )
  9. }

请求

将TLS设置为1.2,以防万一。

  1. [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12


最后,发送您的请求。成功响应的内容将具有Documents数组属性,您可以从中挖掘。

  1. $response = Invoke-WebRequest -Method $verb -Uri $url -ContentType $contentType -Headers $headers -Body $body -UseBasicParsing


我花了很长时间才弄清楚没有分区键的集合的分区键,所以我想我会在这里记录它。如果你需要更多帮助,或者想挖掘更多,请查看这里:
https://learn.microsoft.com/en-us/rest/api/cosmos-db/documents

展开查看全部

相关问题