代码之家  ›  专栏  ›  技术社区  ›  superninja

在cosmos数据库中使用页面大小和页码进行分页

  •  10
  • superninja  · 技术社区  · 6 年前

    我正试图用 PageSize PageNumber . 我知道我们可以设置页面大小 MaxItemCount ,但如何将页码放入此函数中?

    到目前为止我得到的是:

      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;
            }
    
    4 回复  |  直到 6 年前
        1
  •  16
  •   Tur1ng    6 年前

    目前, 分页支持仅基于延续令牌 .

    以下是关于此限制的一些有趣的讨论和功能请求:


    ---延续标记示例---

    下面的示例演示了一种方法(与您的方法非常相似),该方法基于所需的页码、页面大小和延续标记来查询文档:

        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);
        }
    

    现在,下面的示例演示如何通过调用上一个方法检索给定页的文档:

        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 ---");
        }
    
        2
  •  9
  •   PoorInRichfield    5 年前

    skip&take现在可以通过一个新的offset limit子句在cosmos db中使用: https://docs.microsoft.com/en-us/azure/cosmos-db/sql-query-offset-limit

        3
  •  0
  •   user11220586    5 年前

    公共静态列表分页(int pageno=1,int pagesize=20) { list articleslist=新列表(); var collection=urifactory.createdocumentcollectionuri(数据库名,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;
        }
    
    }
    
        4
  •  0
  •   nikolai.serdiuk    5 年前

    有一个解决办法,但不是最佳的:

    ...
    int pageNumber = 1;
    int pageSize = 10;
    ...
        var query = Client.CreateDocumentQuery<T>(
                        UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
                        new FeedOptions { MaxItemCount = pageNumber * pageSize }) // Limit count or returned items
                        .Where(predicate)
                        .AsDocumentQuery();
    
                    var results = new List<T>();
                    int resultsToSkip = (pageNumber - 1) * pageSize;
    
                    while (query.HasMoreResults)
                    {
                        var result = await query.ExecuteNextAsync<T>();
    
                        // Skip pages, not optimal way, the best solution is to use RequestContinuation token.
                        if (resultsToSkip > 0)
                        {
                            resultsToSkip--;
                            continue;
                        }
    
                        results.AddRange(result);
                    }
    
                    return results;
        ...