Я работаю над переносом приложения из Cosmos C # SDK v2 в v3. Я столкнулся с препятствием с разбивкой на страницы и, кажется, не могу этого понять.
У меня есть запрос, который будет искать конкретный контейнер и разбивать запросы на страницы. Мой код настроен для обработки размера страницы (maxItemCount) и токена продолжения. Кроме того, отлично работают первые несколько запросов. Но когда мне нравится четвертая страница, токен продолжения, который я получаю в ответе от Cosmos, недействителен. Это выглядит так:
[{\"range\":{\"min\":\"05C1DFFFFFFFFC\",\"max\":\"FF\"}}]
И когда я передаю это следующему запросу на захват следующей страницы, я получаю следующую ошибку:
Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (CompositeContinuationToken is missing field: 'token': {"range":{"min":"05C1DFFFFFFFFC","max":"FF"}}););););););););
Теперь я обнаружил, что если я изменяю токен продолжения перед его отправкой, я могу добиться успеха запроса. Для этого мне нужно добавить свойство в строку JSON, как вы уже догадались, token
.
Вот рассматриваемый код, который обрабатывает этот запрос:
IQueryable<LeadEntity> query;
var queryResults = new List<LeadEntity>();
var requestOptions = new QueryRequestOptions
{
MaxItemCount = input.Page?.Size ?? Core.Shared.Constants.PageSize.Default
};
if (input.Page?.ContinuationToken == "" || input.Page?.ContinuationToken == null)
{
query = Container.GetItemLinqQueryable<LeadEntity>(false, null, requestOptions);
}
else
{
query = Container.GetItemLinqQueryable<LeadEntity>(false, input.Page.ContinuationToken, requestOptions);
}
if (input.Criteria?.CallKeys.IsActive ?? false)
{
var callKeys = (input.Criteria.CallKeys?.Value ?? Enumerable.Empty<Guid>())
.Select(a => a.ToString());
query = query.Where(entity => callKeys.Contains(entity.CallKey));
}
if (input.Criteria?.AdvisorOids.IsActive ?? false)
{
var advisorOids = (input.Criteria.AdvisorOids?.Value ?? Enumerable.Empty<Guid>())
.Select(a => a.ToString());
query = query.Where(entity => advisorOids.Contains(entity.AdvisorOid));
}
if (input.Criteria?.CreatedOn.IsActive ?? false)
{
var start = input.Criteria.CreatedOn.Value.Start;
var duration = input.Criteria.CreatedOn.Value.Duration;
var end = input.Criteria.CreatedOn.Value.End;
if (start.HasValue && end.HasValue)
{
query = query.Where(entity => start.Value <= entity.Created.On && entity.Created.On <= end.Value);
}
else if (start.HasValue)
{
query = query.Where(entity => start.Value <= entity.Created.On && entity.Created.On <= start.Value.Add(+duration));
}
else if (end.HasValue)
{
query = query.Where(entity => end.Value >= entity.Created.On && entity.Created.On >= end.Value.Add(-duration));
}
else
{
query = query.Where(entity => false);
}
}
if (input.Criteria?.HasPortalKey.IsActive ?? false)
{
query = query.Where(entity => input.Criteria.HasPortalKey.Value
&& entity.PortalKey != null
&& entity.PortalKey != default(Guid).ToString()
);
}
query = query.Where(a => a.IsRemoved.IsDefined() ? !a.IsRemoved : true);
var totalCount = await query.CountAsync(ct);
query = input.Orderings?.Any() ?? false
? query.OrderBy(string.Join(",", input.Orderings))
: query;
query = input.Limit.HasValue
? query.Take(input.Limit.Value)
: query;
var feedIterator = query.ToFeedIterator();
FeedResponse<LeadEntity> feedResults = await feedIterator.ReadNextAsync(ct);
queryResults.AddRange(feedResults);
Console.WriteLine($"[LeadSearchAsync] total operation cost: {feedResults.RequestCharge} RUs");
var output = new PageOutput<LeadOutput>
{
Items = Mapper.Map<IEnumerable<LeadOutput>>(queryResults),
ContinuationToken = feedResults.ContinuationToken,
TotalCount = totalCount
};
return output;
Я искал в Google свою задницу и нашел только несколько случаев, когда это происходило, и обычно это на v2 sdk, а не на v3. Часть меня хочет думать, что я делаю неправильную разбивку на страницы, но, похоже, по большей части это работает.
Любая помощь в решении этой проблемы будет принята с благодарностью. Я не нашел много документации по v3 SDK, касающейся разбивки на страницы, и она явно отличается от v2.