我想知道是否有任何方法可以在使用或不使用Linq提供程序的情况下使用C#对文档进行分页?
场景:我有一个支持分页的API,用户在页面中发送他们想要查看的页面大小,例如:
public virtual async Task<HttpResponseMessage> Get(int? page = DefaultPage, int? pageSize = DefaultPageSize)
然后,我使用这些参数使用以下代码对数据访问层中的数据进行分页:
return query.Skip((pageNumber - 1) * pageSize).Take(pageSize);
“那么问题是什么?”,你可能会问。嗯,这种方法和代码在使用EF和SQL时非常有效。问题是我想开始使用DocumentDB,但他们的Linq实现不支持Skip。我见过的唯一示例包括使用TOP关键字或continuation tokens,不非常适合我,允许用户发送pageNumber和pageSize。
是否有任何实施仍允许我的用户在请求中提供pageNumber
和pageSize
?
答案 0 :(得分:11)
SKIP是SQL的性能问题,由于它们的横向扩展设计,它对NoSQL来说更糟糕。我们使用了MongoDB的SKIP功能,发现它实际上从头开始重新删除所有跳过的行。我们跳过的列表中的后面,查询所用的时间越长。因此,即使它具有SKIP功能,我们也被迫实施更高性能的解决方案。
DocumentDB的产品经理了解这一点并且无法添加SKIP。如果他们打算这样做,我相信他们会在加入TOP时做到这一点。
对于DocumentDB,最有效的方法是使用延续令牌并将所有结果缓存到用户想要的位置(甚至超出预期)。持续令牌可以存活很长时间,因此您无需立即获取所有页面。
答案 1 :(得分:6)
虽然这没有具体回答您的问题,但对于未来的Google员工,Document DB支持通过延续令牌进行分页。我已经详细地写了here。您需要的代码:
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
}
答案 2 :(得分:4)
我意识到这个问题已经有了一个被接受(并且很好说)的答案,但由于这个特定的SO页面是谷歌的最佳结果,因此#DB; DocumentDB跳过&#34;我想我会在这里分享我的解决方案,这实际上只是Larry已经建议的实现。我在Angular中使用了连续标记和缓存来为DocumentDB查询提供了一个不错的分页机制。关键是我还允许排序和过滤,这减少了用户跳转到随机页面甚至跳到结果的最后一页的需要。这是我的解决方案:
http://www.zoeller.us/blog/2017/7/27/paging-results-with-documentdb