首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在CosmosDB中使用CosmosClient进行分页

在CosmosDB中使用CosmosClient进行分页
EN

Stack Overflow用户
提问于 2019-12-12 23:22:20
回答 3查看 3.5K关注 0票数 3

我正在尝试使用SDK v3 CosmosClient而不是旧的DocumentClient来实现分页。

原因是DocumentClient似乎不能很好地转换包含空间函数的LINQ查询(例如:当使用Within()时,我会从DocumentClient得到一个错误,指出方法没有实现)。

分页可以很好地与DocumentClient.CreateDocumentQuery<T>配合使用:

代码语言:javascript
复制
var query = DocumentClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri("master", "features"), feedOptions)
                .Where(t => t.Type == typeof(T).Name)
                .Where(pred)
                .AsDocumentQuery();

string queryContinuationToken = null;
var page = await query.ExecuteNextAsync<T>();
if (query.HasMoreResults)
    queryContinuationToken = page.ResponseContinuation;

我不知道在哪里可以使用CosmosClient和它的Container类来收集一个延续标记:

代码语言:javascript
复制
QueryRequestOptions options = new QueryRequestOptions();
options.MaxItemCount = maxRecords;

FeedIterator<T> feed;

if (continuationToken == "")
    feed = Container.GetItemLinqQueryable<T>(true, null, options).Where(x => x.Type == typeof(T).Name).Where(pred).ToFeedIterator();
else
    feed = Container.GetItemLinqQueryable<T>(true, continuationToken, options).Where(x => x.Type == typeof(T).Name).Where(pred).ToFeedIterator();

FeedIterator似乎有一些IDocumentQuery的成员(比如HasMoreResults),但是我在任何地方都找不到延续标记。

我遗漏了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-12-13 01:27:04

好了,这是我实现的一个Where方法。乍一看似乎很管用。

如果你做var f = feed.ReadNextAsync(),你将不会得到一个FeedResponse类型的对象,阻止你访问令牌。您需要显式声明FeedResponse<T>类型的f

代码语言:javascript
复制
public async Task<(IEnumerable<T> Results, string ContinuationToken)> Where<T>(Expression<Func<T, bool>> pred, int maxRecords = 0, string partitionKey = "", string continuationToken = "") where T : IDocumentModel
{

    QueryRequestOptions options = new QueryRequestOptions();

    if (partitionKey != "")
        options.PartitionKey = new PartitionKey(partitionKey);


    if (maxRecords == 0)
    {
        return (Container.GetItemLinqQueryable<T>(true, null, options).Where(x => x.Type == typeof(T).Name).Where(pred), "");
    }
    else
    {
        options.MaxItemCount = maxRecords;
        string token = "";
        FeedIterator<T> feed;
        List<T> res = new List<T>();

        if (continuationToken == "")
            feed = Container.GetItemLinqQueryable<T>(true, null, options).Where(x => x.Type == typeof(T).Name).Where(pred).ToFeedIterator();
        else
            feed = Container.GetItemLinqQueryable<T>(true, continuationToken, options).Where(x => x.Type == typeof(T).Name).Where(pred).ToFeedIterator();

        Microsoft.Azure.Cosmos.FeedResponse<T> f = await feed.ReadNextAsync();
        token = f.ContinuationToken;

        foreach (var item in f)
        {
            res.Add(item);
        }

        return (res, token);
    }

}
票数 9
EN

Stack Overflow用户

发布于 2020-09-30 22:23:12

在Cosmos SDK的3.12.0版本中,下面的版本可以像预期的那样作为旧版DocumentQuery的几乎适当的替代品。

用于比较的原始DocumentClient方法:

代码语言:javascript
复制
IDocumentQuery<ToDoItem> query = client.CreateDocumentQuery<ToDoItem>(collectionUri)
            .Where(t => t.Description.Contains(searchterm))
            .AsDocumentQuery();

while (query.HasMoreResults)
{
  foreach (ToDoItem result in await query.ExecuteNextAsync())
  {
    log.LogInformation(result.Description);
  }
}

使用CosmosClient,这就变成了:

代码语言:javascript
复制
var database = client.GetDatabase("ToDoItems");
var container = database.GetContainer("Items");

var query = container.GetItemLinqQueryable<ToDoItem>()
     .Where(t => t.Description.Contains(searchTerm))
     .ToFeedIterator();

while (query.HasMoreResults)
{
  foreach (ToDoItem result in await query.ReadNextAsync())
  {
    log.LogInformation(result.Description);
  }    
}

因此,您的查询现在是一个FeedIterator,您可以对其调用HasMoreResultsReadNextAsync

诚然,这不会让你访问FeedIterator上的诊断、请求费用等,但它会干净地浏览结果。

票数 2
EN

Stack Overflow用户

发布于 2021-02-12 19:36:23

代码语言:javascript
复制
IQueryable<returnVModel> query;
var requestOptions = new QueryRequestOptions
{
 MaxItemCount = 20
};
if (Token == "" || Token == null)
{
      query = Container.GetItemLinqQueryable<returnVModel>(false, null, requestOptions).Where(x => x.id == id);
 }
 else
 {
      query = Container.GetItemLinqQueryable<returnVModel>(false, Token, requestOptions).Where(x => x.id == id);
 }
 var ct = new CancellationTokenSource();
 var totalCount = await query.CountAsync(ct.Token); //Total Count
 var feedIterator = query.ToFeedIterator();
 var queryResults = new List<returnVModel>();
 FeedResponse<returnVModel> feedResults = await feedIterator.ReadNextAsync(ct.Token);
 queryResults.AddRange(feedResults); // Output
 var PaginationToken = feedResults.ContinuationToken //Token

第一次我们需要将token作为null传递,从下一页开始传递我们在上一次输出中接收到的token。

分页在v3中运行良好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59307840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档