gpt4 book ai didi

azure - 使用 EnableCrossPartitionQuery 的 CosmosDB CreateDocumentQuery 不会返回结果,但如果指定 PartitionKey 则会返回结果

转载 作者:行者123 更新时间:2023-12-03 05:44:29 27 4
gpt4 key购买 nike

我遇到一个问题,如果我为特定查询指定分区键,我将获得我期望的记录。但是,如果我不指定分区键并将 EnableCrossPartitionQuery 设置为 true,它将不会返回/查找任何文档。

这实际上在我的一个 Cosmos DB 上按预期工作,但在另一个 Cosmos DB 上则不然。相同的记录/文件。

我正在使用以下设置

  1. Microsoft.Azure.DocumentDB NuGet 包版本 2.3.0

  2. 具有无限容量的 Cosmos DB 集合(PartitionKey =应用程序ID)

  3. 关于数据库/集合的三个非常简单的文档,通过 Azure 存储资源管理器手动创建

我的代码如下所示,相当简单。如果 GetDocuments 的调用者传递了一个 partitionKey 值,那么我将通过 FeedOptions 在查询中指定它。否则,我在 FeedOptions 上设置 EnableCrossPartitionQuery。

有效的数据库/集合上的文档与无效的数据库/集合上的文档相同。

我使用相同的分区键(ApplicationId)以相同的方式创建了集合

public async Task<IEnumerable<T>> GetDocuments<T>(Expression<Func<T, bool>> predicate, object partitionKey = null)
{
IDocumentQuery<T> queryDetails = QueryDocument<T>(predicate, partitionKey);

var queryData = await queryDetails.ExecuteNextAsync<T>();

if (queryData.Any())
{
return queryData;
}

return default(IEnumerable<T>);
}

private IDocumentQuery<T> QueryDocument<T>(Expression<Func<T, bool>> predicate, object partitionKey = null)
{
FeedOptions feedOptions;

if (partitionKey == null)
{
feedOptions = new FeedOptions { EnableCrossPartitionQuery = true };
}
else
{
feedOptions = new FeedOptions { PartitionKey = new PartitionKey(partitionKey) };
}

var query = _client.CreateDocumentQuery<T>(DocumentCollectionUri, feedOptions);

var queryDetails = query.Where(predicate).AsDocumentQuery();

return queryDetails;
}

该文档如下所示:

{
"id": "1",
"HubName": "abxyz-hub",
"ClientId": "abxyz",
"ApplicationId": 1,
"ApplicationName": "My App Name",
"_rid": "hSkpAJde99IBAAAAAAAAAA==",
"_self": "dbs/hSkpAA==/colls/hSkpAJde99I=/docs/hSkpAJde99IBAAAAAAAAAA==/",
"_etag": "\"53007677-0000-0100-0000-5cbb3c660000\"",
"_attachments": "attachments/",
"_ts": 1555774566
}

有什么想法为什么这行不通吗?

最佳答案

你的代码是错误的。您的错误在于此检查:

if (queryData.Any())

您在实际取回所有数据之前就已返回。

您的代码使用分区键的原因是因为您的目标是一个物理分区(通过逻辑分区)并且包含的​​数据小于您提供的 MaxItemCount 或 RequestOptions 对象。

Cosmos DB 仅返回分页结果,并且需要调用每个物理分区来获取这些值,有时会多次调用每个分区,在某些情况下,迭代可能返回 0 数据,但下一次可能会返回一些数据。您必须 ExecuteNextAsync 直到 HasMoreResults 为 false。

添加一个 while 循环来从跨分区查询将命中的所有物理分区获取所有分页结果将解决该问题:

这是代码:

public async Task<IEnumerable<T>> GetDocuments<T>(Expression<Func<T, bool>> predicate, object partitionKey = null)
{
IDocumentQuery<T> documentQuery = QueryDocument<T>(predicate, partitionKey);

var results = new List<T>();

while(documentQuery.HasMoreResults)
{
var docs = await documentQuery.ExecuteNextAsync<T>();
results.AddRange(docs)
}

return results;
}

private IDocumentQuery<T> QueryDocument<T>(Expression<Func<T, bool>> predicate, object partitionKey = null)
{
FeedOptions feedOptions;

if (partitionKey == null)
{
feedOptions = new FeedOptions { EnableCrossPartitionQuery = true };
}
else
{
feedOptions = new FeedOptions { PartitionKey = new PartitionKey(partitionKey) };
}

var query = _client.CreateDocumentQuery<T>(DocumentCollectionUri, feedOptions);

var queryDetails = query.Where(predicate).AsDocumentQuery();

return queryDetails;
}

关于azure - 使用 EnableCrossPartitionQuery 的 CosmosDB CreateDocumentQuery 不会返回结果,但如果指定 PartitionKey 则会返回结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55778672/

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