几个小时后,cosmosDB查询缺少结果

时间:2019-08-09 15:29:40

标签: azure-cosmosdb iqueryable

8月6日,我们遇到了一个反复出现的问题,查询我们的cosmosDB。

我们的查询缺少结果,但是我们仍然收到“有效”的答复。对于我们的应用程序,在一些非常批评的查询中未返回批次结果。 例如,一个应该返回250个文档的请求返回了240个。在5到6个小时内,多次查询的结果都不完整。查询的数据是 不可否认地存在于数据库中。

我们正在使用与此类似的代码段进行查询,并使用200个文档进行分页:

public static List<T> ToList<T>(this IDocumentQuery<T> documentQuery)
{
    List<T> documents = new List<T>();
    while (documentQuery.HasMoreResults)
    {
        documents.AddRange(documentQuery.ExecuteNextAsync<T>().Result);
    }
    return documents;
}

通过强制转换IQueryable初始化IDocumentQuery,如下所示:

queryable.AsDocumentQuery()

使用的解决方案类似于在Microsoft文档中找到的解决方案:https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.documents.linq.documentqueryable.asdocumentquery?view=azure-dotnet

我们当前正在将数据解决方案移向cosmosDB,这就是我们注意到该问题的方式。 您有什么想法可能导致这种情况吗?我们应该期待更多相同类型的问题吗?你知道吗 如何确定我们收到的结果不完整?

1 个答案:

答案 0 :(得分:0)

恐怕在使用MaxItemCount方法时,您需要设置CreateDocumentQuery属性,否则MaxItemCount的默认值为-1。如果数据太大,则数据结果集可能会在吞吐量限制内被截断。

您可以参考这种情况:Pagination in Cosmos DB using Page Size and Page Number在这种情况下可以从Continuation Token Example得到一些线索。

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