GroupBy и Pagination не работают вместе CosmosDB - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть следующий класс:

public class RetailProduct
{
    public string OriginalVersionId { get; set; }
    public string Version { get; set; }
    public DateTime AvailableTo { get; set; }
}

И следующий запрос:

public async Task<PagedResponse<RetailProduct>> GetAllRetailProducts(string continuationToken, int pageSize = 10)
    {
        var feedOptions = new FeedOptions
        {
            MaxItemCount = pageSize,
            RequestContinuation = continuationToken
        };

        Uri collectionUri = UriFactory.CreateDocumentCollectionUri(_databaseName, _retailProductCollectionName);

        IDocumentQuery<RetailProduct> query = _client.CreateDocumentQuery<RetailProduct>(collectionUri, feedOptions)
            .GroupBy(g => g.OriginalVersionId)
            .Select(p => p.OrderByDescending(x => x.Version))
            .Select(p => p.FirstOrDefault())
            .Where(r => r.AvailableTo > DateTime.UtcNow || r.AvailableTo == null)
            .AsDocumentQuery();

        if (query.HasMoreResults)
        {
            FeedResponse<RetailProduct> products = await query.ExecuteNextAsync<RetailProduct>();
            return new PagedResponse<RetailProduct>()
            {
                Continuation = products.ResponseContinuation,
                Results = products.ToList()
            };
        }

        return null;
    }

Вышеуказанный метод не удастся, потому что я пытаюсь сделать GroupBy в CosmosDB. Если я изменю его следующим образом, для группировки in-memory я получу свой результат:

public async Task<PagedResponse<RetailProduct>> GetAllRetailProducts(string continuationToken, int pageSize = 10)
        {
            var feedOptions = new FeedOptions
            {
                MaxItemCount = pageSize,
                RequestContinuation = continuationToken
            };

            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(_databaseName, _retailProductCollectionName);

            IDocumentQuery<RetailProduct> query = _client.CreateDocumentQuery<RetailProduct>(collectionUri, feedOptions).AsDocumentQuery();

            if (query.HasMoreResults)
            {
                FeedResponse<RetailProduct> products = await query.ExecuteNextAsync<RetailProduct>();
                var filteredList = products.ToList()
                    .GroupBy(g => g.OriginalVersionId)
                    .Select(p => p.OrderByDescending(x => x.Version))
                    .Select(p => p.FirstOrDefault())
                    .Where(r => r.AvailableTo > DateTime.UtcNow || r.AvailableTo == null);

                return new PagedResponse<RetailProduct>()
                {
                    Continuation = products.ResponseContinuation,
                    Results = filteredList
                };
            }

            return null;
        }

Проблема в том, что, поскольку я выполняю манипуляции с данными в памяти, возвращенный набор данных больше не всегда содержит 10 записей из-за моей фильтрации.

Единственный другой вариант, который я могу придумать, - это рекурсивно вызывать мою функцию, пока результат не будет содержать 10 отфильтрованных записей, а затем вернуться, но это потребует много RU's и станет довольно дорогим.

Я что-то упустил, есть ли другой подход, который я могу предпринять?

...