gpt4 book ai didi

pagination - Cosmos DB .NET SDK V3 Query With Paging 示例需要

转载 作者:行者123 更新时间:2023-12-05 04:47:01 25 4
gpt4 key购买 nike

我正在努力从 MS 中为 v3 SDK 找到用于分页查询的代码示例,他们提供了 V2 的示例,但该 SDK 是使用“CreateDocumentQuery”方法的完全不同的代码库。

我尝试在此处搜索 GitHub:https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/Queries/Program.cs

我相信我正在寻找一个使用延续 token 的方法示例,假设如果我在我的网络应用程序中缓存以前使用的延续 token ,那么我可以向后和向前翻页?

我也不太理解 MS 的解释,因为 MaxItemCount 实际上并不意味着它只会尝试返回 X 个项目,而只是限制每个分区的每次搜索中的项目数量,混淆!

任何人都可以指出代码示例的正确位置吗?我也尝试搜索 https://learn.microsoft.com/en-us/azure/cosmos-db/sql-query-pagination但似乎会引导我们使用较旧的 SDK(我相信是 V2)

更新(根据下面 Gaurav 的评论)

        public async Task<(List<T>, string)> QueryWithPagingAsync(string query, int pageSize, string continuationToken)
{
try
{
Container container = GetContainer();
List<T> entities = new(); // Create a local list of type <T> objects.
QueryDefinition queryDefinition = new QueryDefinition(query);

using FeedIterator<T> resultSetIterator = container.GetItemQueryIterator<T>(
query, // SQL Query passed to this method.
continuationToken, // Value is always null for the first run.
requestOptions: new QueryRequestOptions()
{
// Optional if we already know the partition key value.
// Not relevant here becuase we're passing <T> which could
// be any model class passed to the generic method.
//PartitionKey = new PartitionKey("MyParitionKeyValue"),

// This does not actually limit how many documents are returned if
// what we're querying resides across multiple partitions.
// If we set the value to 1, then control the number of times
// the loop below performs the ReadNextAsync, then we can control
// the number of items we return from this method. I'm not sure
// whether this is best way to go, it seems we'd be calling
// the API X no. times by the number of items to return?
MaxItemCount = 1
});

// Set var i to zero, we'll use this to control the number of iterations in
// the loop, then once i is equal to the pageSize then we exit the loop.
// This allows us to limit the number of documents to return (hope this is the best way to do it)
var i = 0;

while (resultSetIterator.HasMoreResults & i < pageSize)
{
FeedResponse<T> response = await resultSetIterator.ReadNextAsync();
entities.AddRange(response);
continuationToken = response.ContinuationToken;
i++; // Add 1 to var i in each iteration.
}
return (entities, continuationToken);
}
catch (CosmosException ex)
{
//Log.Error($"Entities was not retrieved successfully - error details: {ex.Message}");

if (ex.StatusCode == HttpStatusCode.NotFound)
{
return (null, null);
}
else { throw; }
}
}

上述方法是我最近的尝试,虽然我能够使用和返回延续 token ,但下一个挑战是如何控制从 Cosmos 返回的项目数量。在我的环境中,您可能会注意到上面的方法在我们从不同的调用方法传递模型类的 repo 中使用,因此硬编码分区键是不切实际的,我正在努力配置返回的项目数.上面的方法实际上控制了我返回到链上调用方法的项目数量,但我担心我的方法会导致对 Cosmos 的多次调用,即如果我将页面大小设置为 1000 个项目,我我对 Cosmos 进行了 1000 次 HTTP 调用?

我正在看这里的一个线程 https://stackoverflow.com/questions/54140814/maxitemcount-feed-options-property-in-cosmos-db-doesnt-wor k 但不确定该线程中的答案是否是解决方案,并且考虑到我使用的是 V3 SDK,请求选项中似乎没有可用的“PageSize”参数。

不过,我还在此处找到了官方 Cosmos 代码示例:https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/Queries/Program.cs#L154-L186 (参见示例方法“QueryItemsInPartitionAsStreams”第 171 行),看起来他们使用了类似的模式,即将 MaxItemCount 变量设置为 1,然后控制编号。退出前在循环中返回的项目数。我想我只是想更好地了解这可能对 RU 和对 Cosmos 的 API 调用有什么影响?

最佳答案

请尝试以下代码。它从单个请求中最多包含 100 个文档的容器中获取所有文档。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;

namespace CosmosDbSQLAPISamples
{
class Program
{
private static string connectionString =
"AccountEndpoint=https://account-name.documents.azure.com:443/;AccountKey=account-key==;";
private static string databaseName = "database-name";
private static string containerName = "container-name";
static async Task Main(string[] args)
{
CosmosClient client = new CosmosClient(connectionString);
Container container = client.GetContainer(databaseName, containerName);
string query = "Select * From Root r";
string continuationToken = null;
int pageSize = 100;
do
{
var (entities, item2) = await GetDataPage(container, query, continuationToken, pageSize);
continuationToken = item2;
Console.WriteLine($"Total entities fetched: {entities.Count}; More entities available: {!string.IsNullOrWhiteSpace(continuationToken)}");
} while (continuationToken != null);
}

private static async Task<(List<dynamic>, string)> GetDataPage(Container container, string query, string continuationToken, int pageSize)
{
List<dynamic> entities = new(); // Create a local list of type <T> objects.
QueryDefinition queryDefinition = new QueryDefinition(query);
QueryRequestOptions requestOptions = new QueryRequestOptions()
{
MaxItemCount = pageSize
};
FeedIterator<dynamic> resultSetIterator = container.GetItemQueryIterator<dynamic>(query, continuationToken, requestOptions);
FeedResponse<dynamic> response = await resultSetIterator.ReadNextAsync();
entities.AddRange(response);
continuationToken = response.ContinuationToken;
return (entities, continuationToken);
}
}
}

更新

我想我现在明白你的顾虑了。从本质上讲,您需要考虑两件事:

  1. MaxItemCount - 这是 Cosmos DB 将在单个请求中返回的最大文档数。请注意,您可以获得 0 到为此参数指定的值之间的任何值。例如,如果您指定 100 作为 MaxItemCount,您可以在单个请求中获取 0 到 100 个文档。
  2. FeedIterator - 它在内部跟踪延续 token 。根据收到的响应,如果找到继续标记,它会将 HasMoreResults 设置为 true 或 false。 HasMoreResults 的默认值为 true。

现在来看你的代码,当你做类似的事情时:

while (resultSetIterator.HasMoreResults)
{
//some code here...
}

因为 FeedIterator 跟踪延续标记,所以此循环将返回与查询匹配的所有文档。如果您注意到,在我的代码中我没有使用这个逻辑。我只是发送一次请求,然后返回结果。

我认为将 MaxItemCount 设置为 1 是个坏主意。如果您想获取 100 个,那么您至少要向您的 Cosmos DB 帐户发出 100 个请求。如果您非常需要从您的 API 中获取 100 个(或任何固定数量)文档,您可以实现自己的分页逻辑。例如,请看下面的代码。它在单个请求中总共获取 1000 个文档,最多 100 个文档。

static async Task Main(string[] args)
{
CosmosClient client = new CosmosClient(connectionString);
Container container = client.GetContainer(databaseName, containerName);
string query = "Select * From Root r";
string continuationToken = null;
int pageSize = 100;
int maxDocumentsToFetch = 1000;
List<dynamic> documents = new List<dynamic>();
do
{
var numberOfDocumentsToFetch = Math.Min(pageSize, maxDocumentsToFetch);
var (entities, item2) = await GetDataPage(container, query, continuationToken, numberOfDocumentsToFetch);
continuationToken = item2;
Console.WriteLine($"Total entities fetched: {entities.Count}; More entities available: {!string.IsNullOrWhiteSpace(continuationToken)}");
maxDocumentsToFetch -= entities.Count;
documents.AddRange(entities);
} while (maxDocumentsToFetch > 0 && continuationToken != null);
}

关于pagination - Cosmos DB .NET SDK V3 Query With Paging 示例需要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68643111/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com