Count items with query using readItems(queryString)

270 Views Asked by At

I want to count the number of items in a container.

Using SELECT value count(1) FROM tasks WHERE tasks.TaskState = 0 OR (tasks.TaskState = 4 AND tasks.RetryCount <= 3) works on the Azure Portal and now I want to do the same on the server side.

I tried to do this, but this don't work...

await this.Container.RetrieveItemsAsync<int>(new Query(CreateNumberOfTasksQuery()), cancellationToken: cancellationToken).ConfigureAwait(false);

And my query is:

"SELECT value count(1) FROM tasks WHERE tasks.TaskState = 0 OR (tasks.TaskState = 4 AND tasks.RetryCount <= 3)";

And I can't retrieve the item since int is not a reference type...

error

The implementation class:

public async Task<IList<T>> RetrieveItemsAsync<T>(Query query, QueryOptions queryOptions = null, CancellationToken cancellationToken = default)
    where T : class
{
    // Validation

    SmartGuard.Check(() => query, typeof(T) != typeof(string), Properties.Resources.RES_Exception_MultiModel_Argument_UnsupportedType.Format(typeof(string)));
    SmartGuard.NotNull(() => query, query);

    // Logging

    this.Service.Logger.LogDebug($"Retrieving items...");

    // Delegate on instance
    // Make sure the exceptions handler is called

    IList<T> result = await CosmosDbMultiModelDatabaseExceptionHandler.HandleAsync(
        OperationTarget.Item,
        async () =>
        {
            IList<T> result = new List<T>();

            Cosmos.FeedIterator<T> feedIterator = this.Instance.GetItemQueryIterator<T>(
                queryDefinition: query.ToQueryDefinition(),
                requestOptions: queryOptions.ToQueryRequestOptions());

            while (feedIterator.HasMoreResults)
            {
                foreach (T item in await feedIterator.ReadNextAsync(cancellationToken).ConfigureAwait(false))
                {
                    result.Add(item);
                }
            }

            return result;
        })
        .ConfigureAwait(false);

    // Logging

    this.Service.Logger.LogDebug($"{result.Count} items were retrieved.");

    // Result

    return result;
}
1

There are 1 best solutions below

2
On BEST ANSWER

This is because where T : class constraints your type must be a reference type.

You can overload your RetrieveItemsAsync method,

public async Task<IList<T>> RetrieveItemsAsync<T>(T value,Query query, QueryOptions queryOptions = null, CancellationToken cancellationToken = default)
    where T : struct
{
.....
}

then you can try this:

await this.Container.RetrieveItemsAsync<int>(Int32.MaxValue,new Query(CreateNumberOfTasksQuery()), cancellationToken: cancellationToken).ConfigureAwait(false);