【问题标题】:CosmosDb c# SDK is not working on contrary to the Rest ApiCosmosDb c# SDK 与 Rest Api 不兼容
【发布时间】:2018-09-25 13:32:56
【问题描述】:

我正在使用 CosmosDb Sdk 和 nuget Microsoft.Azure.DocumentDB.Core 2.1.0.NetStandard 2.0

我正在使用此查询来获取文档

var client client = new DocumentClient(new Uri(config.CosmosDbEndPointUrl), config.CosmosDbPrimaryKey);
var partitionKey = "siteId"; // the partition key is defined as /siteId, I tried both, still not working
var queryOptions = new FeedOptions
{
  MaxItemCount = 500,
  EnableCrossPartitionQuery = true,
  PartitionKey = new PartitionKey(partitionKey)
};

var auditQuery = client
    .CreateDocumentQuery<AuditDTO>(
     UriFactory.CreateDocumentCollectionUri(_databaseName, _collectionName), queryOptions)
        .Where(f => f.Status == AuditStatus.Pending)
        .AsDocumentQuery();

var results = new List<AuditDTO>();
while (auditQuery.HasMoreResults)
{
  var audits = await auditQuery.ExecuteNextAsync<AuditDTO>();
  results.AddRange(audits);
}

此查询返回 0 个文档。

我的查询基于this tutorial

我认为有些参数不正确所以我尝试使用Rest Api,代码基于this example(见评论EXECUTE a query

var client = new System.Net.Http.HttpClient();
string response = string.Empty;
string authHeader = string.Empty;
string verb = string.Empty;
string resourceType = string.Empty;
string resourceId = string.Empty;
string resourceLink = string.Empty;
client.DefaultRequestHeaders.Add("x-ms-date", utc_date);
client.DefaultRequestHeaders.Add("x-ms-version", "2017-02-22");

verb = "POST";
resourceType = "docs";
resourceLink = $"dbs/{databaseId}/colls/{collectionId}/docs";
resourceId = (idBased) ? $"dbs/{databaseId}/colls/{collectionId}" : collectionId.ToLowerInvariant();

authHeader = GenerateMasterKeyAuthorizationSignature(verb, resourceId, resourceType, masterKey, "master", "1.0");

client.DefaultRequestHeaders.Remove("authorization");
client.DefaultRequestHeaders.Add("authorization", authHeader);
client.DefaultRequestHeaders.Add("x-ms-documentdb-isquery", "True");
client.DefaultRequestHeaders.Add("x-ms-documentdb-query-enablecrosspartition", "true");
client.DefaultRequestHeaders.Add("x-ms-partition-key", "[\"siteId\"]");

var qry = new SqlQuerySpec { query = "SELECT * FROM root WHERE (root[\"status\"] = 0)" };
var r = await client.PostWithNoCharSetAsync(new Uri(baseUri, resourceLink), qry);
var s = await r.Content.ReadAsStringAsync();

如我所料,使用 Rest Api 返回 1 个文档。

我尝试反序列化对类 AuditDTO 的响应,它可以工作,所以我的模型没有问题。

我不明白为什么 Rest Api 有效,而不是 .Net Sdk。

没有授权异常,没有错误信息。我只得到 0 个文档。

我错过了什么?

【问题讨论】:

    标签: c# azure azure-cosmosdb


    【解决方案1】:
    var partitionKey = "siteId";
    var queryOptions = new FeedOptions
    {
      MaxItemCount = 500,
      EnableCrossPartitionQuery = true,
      PartitionKey = new PartitionKey(partitionKey)
    };
    

    您的问题出在分区键上。 分区键应该是分区键的值而不是定义。

    这意味着FeedOptions 上的partitionKey 值应该看起来像这样59c49da3-b398-4db7-aff4-d2129353e3a8(假设它是一个guid)而不是这个siteId

    正确的 FeedOptions 对象如下所示:

    var partitionKey = "59c49da3-b398-4db7-aff4-d2129353e3a8";
    var queryOptions = new FeedOptions
    {
      MaxItemCount = 500,
      EnableCrossPartitionQuery = true,
      PartitionKey = new PartitionKey(partitionKey)
    };
    

    【讨论】:

      【解决方案2】:

      文档确实具有误导性。

      要启用 CrossPartition 查询来查询所有分区,您只需将 EnableCrossPartitionQuery 设置为 true 即可!

      var queryOptions = new FeedOptions
      {
        MaxItemCount = 500,
        EnableCrossPartitionQuery = true
      };
      

      正如 Nick Chapsas 所说,如果您需要搜索特定分区,请将 PartitionKey 属性设置为您要搜索的分区的值。

      这是我在 Azure GitHub 上找到的 a sample

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-01
        • 2016-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多