web-dev-qa-db-fra.com

Pagination dans Cosmos DB à l'aide de la taille et du numéro de page

J'essaye de renvoyer des articles de cosmosDB en utilisant PageSize et PageNumber. Je sais que nous pouvons définir la taille de la page dans MaxItemCount, mais comment mettre le numéro de page dans cette fonction?

Voici ce que j'ai obtenu jusqu'à présent:

  public async Task<IEnumerable<T>> RunSQLQueryAsync(string queryString, int pageSize, int pageNumber)
        {
            var feedOptions = new FeedOptions { MaxItemCount = pageSize, EnableCrossPartitionQuery = true };
            IQueryable<T> filter = _client.CreateDocumentQuery<T>(_collectionUri, queryString, feedOptions);
            IDocumentQuery<T> query = filter.AsDocumentQuery();
            var currentPageNumber = 0;
            var documentNumber = 0;
            List<T> results = new List<T>();
            while (query.HasMoreResults)
            {
                foreach (T t in await query.ExecuteNextAsync())
                {
                    results.Add(t);
                    documentNumber++;
                }
                currentPageNumber++;
                return results;

            }
            return null;
        }
12
superninja

Actuellement, la prise en charge de la pagination est basée uniquement sur le jeton de continuation .

Trouvez ci-dessous quelques discussions intéressantes et demandes de fonctionnalités sur cette limitation:


--- Exemple de jeton de continuation ---

L'exemple suivant illustre une méthode (très similaire à la vôtre) qui interroge des documents en fonction du numéro de page, de la taille de page et du jeton de continuation souhaités:

    private static async Task<KeyValuePair<string, IEnumerable<CeleryTask>>> QueryDocumentsByPage(int pageNumber, int pageSize, string continuationToken)
    {
        DocumentClient documentClient = new DocumentClient(new Uri("https://{CosmosDB/SQL Account Name}.documents.Azure.com:443/"), "{CosmosDB/SQL Account Key}");

        var feedOptions = new FeedOptions {
            MaxItemCount = pageSize,
            EnableCrossPartitionQuery = true,

            // IMPORTANT: Set the continuation token (NULL for the first ever request/page)
            RequestContinuation = continuationToken 
        };

        IQueryable<CeleryTask> filter = documentClient.CreateDocumentQuery<CeleryTask>("dbs/{Database Name}/colls/{Collection Name}", feedOptions);
        IDocumentQuery<CeleryTask> query = filter.AsDocumentQuery();

        FeedResponse<CeleryTask> feedRespose = await query.ExecuteNextAsync<CeleryTask>();

        List<CeleryTask> documents = new List<CeleryTask>();
        foreach (CeleryTask t in feedRespose)
        {
            documents.Add(t);
        }

        // IMPORTANT: Ensure the continuation token is kept for the next requests
        return new KeyValuePair<string, IEnumerable<CeleryTask>>(feedRespose.ResponseContinuation, documents);
    }

Maintenant, l'exemple suivant illustre comment récupérer des documents pour une page donnée en appelant la méthode précédente:

    private static async Task QueryPageByPage()
    {
        // Number of documents per page
        const int PAGE_SIZE = 3;

        int currentPageNumber = 1;
        int documentNumber = 1;

        // Continuation token for subsequent queries (NULL for the very first request/page)
        string continuationToken = null;

        do
        {
            Console.WriteLine($"----- PAGE {currentPageNumber} -----");

            // Loads ALL documents for the current page
            KeyValuePair<string, IEnumerable<CeleryTask>> currentPage = await QueryDocumentsByPage(currentPageNumber, PAGE_SIZE, continuationToken);

            foreach (CeleryTask celeryTask in currentPage.Value)
            {
                Console.WriteLine($"[{documentNumber}] {celeryTask.Id}");
                documentNumber++;
            }

            // Ensure the continuation token is kept for the next page query execution
            continuationToken = currentPage.Key;
            currentPageNumber++;
        } while (continuationToken != null);

        Console.WriteLine("\n--- END: Finished Querying ALL Dcuments ---");
    }
16
Evandro Paula

Skip & take est désormais disponible dans Cosmos DB via une nouvelle clause OFFSET LIMIT: https://docs.Microsoft.com/en-us/Azure/cosmos-db/sql-query-offset-limit

9
PoorInRichfield

pagination de liste statique publique (int pageNo = 1, int pageSize = 20) {List ArticlesList = new List (); var collection = UriFactory.CreateDocumentCollectionUri (databaseName, loginCollectionId);

    using (client = new DocumentClient(new Uri(endpointUrl), primaryKey))
    {

        var optionss = new FeedOptions
        {
            MaxItemCount = (pageNo!=1)?((pageNo-1)*pageSize): ((pageNo) * pageSize)
        };

        var query1 = client.CreateDocumentQuery<ArticlesListDetails>(collection, optionss).OrderByDescending(x => x._ts).AsDocumentQuery();

        var res = query1.ExecuteNextAsync<ArticlesListDetails>().Result;
        if (pageNo == 1)
        {
            return   ArticlesList = res.ToList();
        }
        else
        {
            var options = new FeedOptions
            {
                MaxItemCount = pageSize,
                RequestContinuation = res.ResponseContinuation
            };

            var query = client.CreateDocumentQuery<ArticlesListDetails>(collection, options).OrderByDescending(x => x._ts).AsDocumentQuery();

            while (query.HasMoreResults)
            {
                return  ArticlesList = query.ExecuteNextAsync<ArticlesListDetails>().Result.ToList();
            }
        }

        return ArticlesList;
    }

}
0
user11220586