[英]How to get total count from a filtered FeedIterator in Cosmos DB
I have the following code to filter some data in a 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;
}
The query can yield many records, hence I need the pagination .查询可以产生许多记录,因此我需要pagination 。
Unfortunately I need the total count of the items - and it can vary according to the filtering.不幸的是,我需要项目的总数- 它可能会根据过滤而有所不同。
According to this answer , I have only 2 options:根据这个答案,我只有两个选择:
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: 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}");
I translate my complex SQL query to LINQ and use its Count
method:我将复杂的 SQL 查询转换为 LINQ 并使用其Count
方法:
//should be formatted as code //应该格式化为代码
var count = container.GetItemLinqQueryable(true).Count(item => item.tenantId.Equals('5d484526d76e9653e6226aa2')); var count = container.GetItemLinqQueryable(true).Count(item => item.tenantId.Equals('5d484526d76e9653e6226aa2'));
Both seems quite cumbersome for such a simple task so I wonder if there is any better or more effective approach.对于这样一个简单的任务,两者似乎都很麻烦,所以我想知道是否有更好或更有效的方法。
What else could I try?我还能尝试什么?
Here's roughly the code I've used to perform count operations with .NET SDK v3 based on an arbitrary QueryDefinition
.这大致是我用来执行计数操作的代码 .NET SDK v3 基于任意QueryDefinition
。 There are a few aspects not shown like the full logic of deserialization with System.Text.Json, but hopefully the gist comes across.有几个方面没有显示,例如使用 System.Text.Json 进行反序列化的完整逻辑,但希望能够理解要点。 The idea is to provide a query with base:这个想法是提供一个带有基础的查询:
SELECT VALUE COUNT(1) FROM c
To get a single document as result which contains the result count;获取包含结果计数的单个文档作为结果;
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;
}
Helper class to deserialize the response:帮助程序 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.