簡體   English   中英

如何從 Cosmos DB 中過濾的 FeedIterator 獲取總數

[英]How to get total count from a filtered FeedIterator in Cosmos DB

我有以下代碼來過濾 Cosmos DB 中的一些數據:

Container container = await service.GetContainer(containerName, partitionKeyA);
using (FeedIterator<T> resultSet = container.GetItemQueryIterator<T>(
    queryDefinition: GetComplexSQLQueryDefinition(),
    paginationInfo.Token,
    requestOptions: new QueryRequestOptions()
    {
      PartitionKey = new PartitionKey(partitionKey),
      MaxItemCount = 10
    }
    ))
{ 
  FeedResponse<T> response = await resultSet.ReadNextAsync();
  //get total count
  int totalCount = -1;
}

查詢可以產生許多記錄,因此我需要pagination

不幸的是,我需要項目的總數- 它可能會根據過濾而有所不同。

根據這個答案,我只有兩個選擇:

  1. I create a second SQL query that uses an SQL select command to count the records - then query the database again to select the actual records:

     var query = new QueryDefinition("SELECT value count(1) FROM c WHERE c.tenantId = @type"); query.WithParameter("@type", '5d484526d76e9653e6226aa2'); var container = client.GetContainer("DatabaseName", "CollectionName"); var iterator = container.GetItemQueryIterator<int>(query); var count = 0; while (iterator.HasMoreResults) { var currentResultSet = await iterator.ReadNextAsync(); foreach (var res in currentResultSet) { count += res; } } Console.WriterLine($"The first count is: {count}");
  2. 我將復雜的 SQL 查詢轉換為 LINQ 並使用其Count方法:

    //應該格式化為代碼

    var count = container.GetItemLinqQueryable(true).Count(item => item.tenantId.Equals('5d484526d76e9653e6226aa2'));

對於這樣一個簡單的任務,兩者似乎都很麻煩,所以我想知道是否有更好或更有效的方法。

我還能嘗試什么?

這大致是我用來執行計數操作的代碼 .NET SDK v3 基於任意QueryDefinition 有幾個方面沒有顯示,例如使用 System.Text.Json 進行反序列化的完整邏輯,但希望能夠理解要點。 這個想法是提供一個帶有基礎的查詢:

SELECT VALUE COUNT(1) FROM c

獲取包含結果計數的單個文檔作為結果;

public async Task<int?> CountAsync(QueryDefinition query, string partitionKey)
{
    var options = new QueryRequestOptions() { PartitionKey = new(partitionKey), MaxItemCount = 1 };
    int? count = null;
    using var resultSet = cosmosService.DataContainer.GetItemQueryStreamIterator(query, requestOptions: options);
    while (resultSet.HasMoreResults)
    {
        using var response = await resultSet.ReadNextAsync();
        if (response.IsSuccessStatusCode)
        {
            // Deserialize response into CosmosResponse<int>
            var deserializeResult = await FromJsonStream<CosmosResponse<int>>(response.Content);
            if (!deserializeResult.HasSuccessValue(out CosmosResponse<int>? responseContent))
            {
                return null; // Or some failure
            }

            if (responseContent.Documents.Any())
            {
                count = responseContent.Documents[0];
                break;
            }
            else
            {
                return null;// Or some failure
            }
        }
        else // Unexpected status. Abort processing.
        {
            return null;// Or some failure
        }
    }

    return count;
}

幫助程序 class 反序列化響應:

public class CosmosResponse<T>
{
    [JsonPropertyName("Documents")]
    public IReadOnlyList<T> Documents { get; set; } = Array.Empty<T>();

    [JsonPropertyName("_count")]
    public int Count { get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM