使用C#对DocumentDB进行分页,无需跳过

使用C#对DocumentDB进行分页,无需跳过,c#,linq,pagination,azure-cosmosdb,C#,Linq,Pagination,Azure Cosmosdb,我想知道是否有任何方法可以在有或没有Linq提供程序的情况下,针对DocumentDB在C#中实现分页 场景:我有一个支持分页的API,用户在要查看的页面中发送一个页面大小,例如: 公共虚拟异步任务Get(int?page=DefaultPage,int?pageSize=DefaultPageSize) 然后,我使用这些参数使用以下代码对数据访问层中的数据进行分页: 返回查询。跳过((页码-1)*pageSize)。获取(页面大小) “那有什么问题?”你可能会问。在使用EF和SQL时,这种方法

我想知道是否有任何方法可以在有或没有Linq提供程序的情况下,针对DocumentDB在C#中实现分页

场景:我有一个支持分页的API,用户在要查看的页面中发送一个页面大小,例如:

公共虚拟异步任务Get(int?page=DefaultPage,int?pageSize=DefaultPageSize)

然后,我使用这些参数使用以下代码对数据访问层中的数据进行分页:

返回查询。跳过((页码-1)*pageSize)。获取(页面大小)

“那有什么问题?”你可能会问。在使用EF和SQL时,这种方法和代码非常有效。问题是我想开始使用DocumentDB,但是他们的Linq实现不支持Skip。我见过的唯一例子包括使用关键字或不符合我的要求,允许用户发送页码和页面大小


是否有任何实现仍然允许我的用户在请求中提供
pageNumber
pageSize

跳过是SQL的一个性能问题,而NoSQL由于其向外扩展设计,其性能更差。我们使用了MongoDB的SKIP功能,发现它实际上是从头开始重新运行查询,丢弃所有跳过的行。我们跳到的列表越晚,查询花费的时间就越长。因此,即使它具有跳过功能,我们也被迫实现一个更高性能的解决方案

DocumentDB的产品经理了解这一点,并抵制添加SKIP。如果他们真的要这么做,我相信当他们加入TOP时,他们会这么做的


对于DocumentDB,最有效的方法是使用continuation令牌并缓存所有结果,以达到用户想要的(甚至可以预期的)目的。延续标记可以保存很长一段时间,因此您不需要立即获取所有页面。

虽然这并不能明确回答您的问题,但对于未来的谷歌用户,Document DB支持通过延续标记进行分页。我已经写得很详细了。您需要的代码如下所示:

var endpoint = "document db url";  
var primaryKey = "document db key";  
var client = new DocumentClient(new Uri(endpoint), primaryKey);  
var collection = UriFactory.CreateDocumentCollectionUri("database id", "collection id");

var options = new FeedOptions  
{ 
    MaxItemCount = 100 // <- Page size
};

var query = client.CreateDocumentQuery<Document>(collection, options).AsDocumentQuery();

while (query.HasMoreResults)  
{
    var result = await query.ExecuteNextAsync<Document>();

    // Process paged results
}
var endpoint=“文档数据库url”;
var primaryKey=“文档数据库键”;
var client=newdocumentclient(新Uri(端点),primaryKey);
var collection=UriFactory.CreateDocumentCollectionUri(“数据库id”、“集合id”);
var选项=新的馈线选项
{ 

MaxItemCount=100/我意识到这个问题已经有了一个公认的答案(而且说得很好),但由于这个特殊的SO页面是Google上“DocumentDB skip”的最高结果我想我会在这里分享我的解决方案,这实际上只是Larry已经建议的一个实现。我使用continuation令牌和Angular中的缓存为DocumentDB查询提供了一个体面的分页机制。关键是我还允许排序和过滤,从而减少了用户跳转到随机页面或甚至其他页面的需要到结果的最后一页。以下是我的解决方案:


你好,拉里,谢谢你的回答,这听起来是一个合理的论点。虽然我不知道如果我的用户可以发送任何
页面
页面大小
组合,使用延续令牌和缓存结果将如何可行。是的,页面的最高值等于收藏,但这不是“不可能”吗要将其与
page
pageSize
组合生成的所有不同组合一起缓存,请注意
pageSize
可以是从1到大约50的所有内容。假设用户已将页面大小设置为10,缓存中有27行。因此,缓存中只有足够的行用于第1页、第2页和部分页面3当用户请求第7页时在内存中。您的代码将计算出缓存中至少需要80行才能显示第7页,并将使用上一个请求中的延续标记获取那么多行。如果用户随后跳回到第5页,则缓存中已经有了该行,并且不需要在prac中点击DocumentDBtice您可以在两位数毫秒内获得100行甚至1000行。感谢您的解释。这听起来是一个不错的策略,特别是它的动态性足以让我的用户在不同的请求之间更改
页面大小。我想您也可以在单个资源的请求中使用内置缓存,这是很好。请注意,延续令牌永远不会过期这是一个很好的解决方案。我非常希望看到它更新为支持在导航中显示所有页面(随机跳转),而不仅仅是下一页。如果我有额外的过滤器作为
。Where()
?延续令牌会自动保留到下一页吗?