Azure cosmosdb Azure Cosmos多个呼叫的Microsoft.Azure.Documents.Client

Azure cosmosdb Azure Cosmos多个呼叫的Microsoft.Azure.Documents.Client,azure-cosmosdb,Azure Cosmosdb,我试图理解为什么Microsoft.Azure.Documents.Client在运行查询时会多次调用 var option=newfeedoptions{enableCrospartitionQuery=true,MaxItemCount=100} var myobj = cosmosClient.CreateDocumentQuery<myCosmosObj>(documentUri, option) .Wh

我试图理解为什么Microsoft.Azure.Documents.Client在运行查询时会多次调用


var option=newfeedoptions{enableCrospartitionQuery=true,MaxItemCount=100}

                var myobj = cosmosClient.CreateDocumentQuery<myCosmosObj>(documentUri, option)
                    .Where(x => x.ID == request.Id);


                while (myobj.AsDocumentQuery().HasMoreResults)
                {
                    var results = await myobj.AsDocumentQuery().ExecuteNextAsync<myCosmosObj>();

                    resultList.AddRange(results);
                }
var myobj=cosmosClient.CreateDocumentQuery(documentUri,选项)
。其中(x=>x.ID==request.ID);
while(myobj.AsDocumentQuery().HasMoreResults)
{
var results=await myobj.AsDocumentQuery().ExecuteNextAsync();
resultList.AddRange(结果);
}
Fiddler跟踪显示对cosmos集合dbs/mycollectionname/colls/docs的5次调用(上面的while循环运行5次)


我的问题是1个网络跃点可以提高性能,所以我想了解它为什么要进行5次网络调用,以及我是否需要对配置进行一些调整。我已经尝试过调整ResultSize。这大约是一个3GB的集合。

使用分区集合,这是最有效的方法通过id创建文档也是通过指定分区键(然后将查询定向到单个分区)实现的。没有PK,实际上无法预先知道文档将驻留在哪个分区中。这可能就是您看到5个调用的原因(您可能有5个分区)

代码显示的另一种方法是进行跨分区查询,每个分区必须进行一次查询,以查找您要查找的文档


还有一点需要注意:查询的RU成本比读取高。如果您已经知道分区键和id,则无需调用查询引擎(因为对于给定的分区键+行键组合,您只能检索单个文档)大卫的答案在理论上是正确的,但它缺少一个关键点

您的代码错误。您在循环中创建文档查询的方式意味着您将始终查询第一次执行的结果5次

代码实际上应该是这样的:

var query = cosmosClient.CreateDocumentQuery<myCosmosObj>(documentUri, option)
        .Where(x => x.ID == request.Id).AsDocumentQuery();

while (query.HasMoreResults)
{
    var results = await query.ExecuteNextAsync<myCosmosObj>();
    resultList.AddRange(results);
}
var query=cosmosClient.CreateDocumentQuery(documentUri,选项)
.Where(x=>x.ID==request.ID).AsDocumentQuery();
while(query.HasMoreResults)
{
var results=await query.ExecuteNextAsync();
resultList.AddRange(结果);
}

这将正确运行您的查询,并且它将使用查询对象的continuation属性来读取
ExecuteNextAsync

中的下一页。您的集合是固定的10GB还是分区的?如果分区:您启用了跨分区查询。并且您没有指定分区键。因此,它必须使用hin每个分区。可能会有其他情况发生,但在你的问题中没有显示任何痕迹,这很难说。是的,它是分区的,所以我需要在代码中指定分区键,我猜?正确-请参阅下面发布的我的答案。我还指出了一些关于读取与查询的内容。
EnableCrossPartitionQuery
将必须将请求的头添加到CosmosDB。这是一条指令,告诉引擎在内部搜索所有分区。它不应该导致多个调用。这项工作应该在服务器端完成。将
MaxItemCount
更改为-1实际上会证明.var option=new FeedOptions{EnableCrossPartitionQuery=true,MaxItemCount=-1};仍进行了5次调用。@David您是指此()中的读取吗?我的文档上有一个自定义ID属性,而我我使用它作为分区键,看起来这个调用引用的是Cosmos分配的id,我在我的应用程序中不知道这个值。@cjsmith411-是的。我没有意识到你使用了不同的id属性。这仍然会进行5次调用,使得while子句上方的AsDocumentQuery行也一样。循环是否在进行这5次调用但是?我希望它是SDK本身。我相信SDK正在进行调用,因为它来自query.HasMoreResults