对分区的 CosmosDB 集合的查询不一致
Inconsistent querying on a partitioned CosmosDB collection
我有一个分区的 cosmos DB 集合,定义为无限制,吞吐量为 1000。它具有以下文档结构:
"Id": "b42129d2-5467-450c-9f7e-744f78dfe1e7", // Primary key
"ArrayOfObjects": [
{
// other properties omitted for brevity
"SubId": "ed2a49fb-51d4-45b4-9690-df0721d6a32f"
},
{
"SubId": "35c87833-9bea-4151-86da-4d9c482ae1fe"
},
"ParitionKey": "b42"
分区键是GUID主键的前3个字母。这给了我 32768 个具有良好基数的可能分区。我正在使用 CosmosDB .NetCore SDK。目前在约 6 千个分区中有约 17 万个文档。
我有一些功能需要通过 "SubId" 从集合中检索文档,但我不知道主键,这意味着我不知道分区键。不幸的是,我无法更改此功能以使用主键,因为它的依赖项是无法修改的遗留系统。
发生的事情是,我成功创建了一个新文档,然后在某个时候我需要使用 "SubId" 查询该文档。这是在 C# 中完成的,如下所示:
public async Task<DocumentModel> GetBySubId(string subId)
{
var collectionId = _cosmosClient.CollectionId;
var query = $@"SELECT * FROM {collectionId} c
WHERE ARRAY_CONTAINS(c.ArrayOfObjects, {{'SubId': '{subId}'}}, true)";
var feedOptions = new FeedOptions { EnableCrossPartitionQuery = true };
var docQuery = _cosmosClient.Client.CreateDocumentQuery(
_collectionUri,
query,
feedOptions)
.AsDocumentQuery();
var executedQuery = await docQuery.ExecuteNextAsync<DocumentModel>();
if (executedQuery.Count == 0)
{
return null;
}
return executedQuery.FirstOrDefault();
}
有时查询成功有时不成功,我 return 为空,然后从我的控制器我 return 一个 404。
为什么这很奇怪是因为如果我检查数据库并且 运行 直接查询文档就在那里并且实际上并没有丢失,但是由于某种原因当我使用 SDK 从 C# 查询时它找不到文档。我还有其他功能可以使用主键(现在意味着我有分区键)和 SubId 进行查询,并且工作正常。只有当我使用 SubId 本身查询时(没有分区键)它找不到文档。
鉴于以上情况,我认为这与没有分区键的查询有关。在没有分区键的情况下查询时我遗漏了什么?
我目前尝试的是将 database consistency 从 Eventual 设置为 Strong。这似乎没有任何区别。
What I've tried at the moment is setting the database consistency from
Eventual to Strong. This doesn't seem to make any difference.
由此 document,Strong
级别一致性保证返回项目的最新提交版本。根据你的描述,你测试的环境不是高并发读操作。所以,我认为这与一致性水平无关。
Sometimes it queries successfully sometimes it doesn't and I return
null, then from my controller I return a 404.
根据我的经验,由于吞吐量瓶颈,这个问题反复无常。查询分区集合时需要提供分区键。但是,您不知道分区键,只有在您设置示例代码中已经存在的 EnableCrossPartitionQuery = true
后才能完成。然后您的查询将跨越整个分区,直到找到特定文档。另外,array_contains
算子增加了查询的负担。
Cosmos DB 查询受吞吐量设置限制,不会覆盖整个数据库 endlessly.Please 请参阅此 document。
由于您现在无法调整您的分区策略,我建议您增加吞吐量设置来检查问题。
我来自 CosmosDB 工程团队。
您提到的行为可能是因为有时查询无法在一次继续中完成执行。请确保查询通过耗尽延续来完成执行。您可以在此处找到示例:https://docs.microsoft.com/en-us/azure/cosmos-db/performance-tips#throughput。在 IDocumentQuery.HasMoreResults 设置为 false 之前,查询执行不会被视为完成。
我有一个分区的 cosmos DB 集合,定义为无限制,吞吐量为 1000。它具有以下文档结构:
"Id": "b42129d2-5467-450c-9f7e-744f78dfe1e7", // Primary key
"ArrayOfObjects": [
{
// other properties omitted for brevity
"SubId": "ed2a49fb-51d4-45b4-9690-df0721d6a32f"
},
{
"SubId": "35c87833-9bea-4151-86da-4d9c482ae1fe"
},
"ParitionKey": "b42"
分区键是GUID主键的前3个字母。这给了我 32768 个具有良好基数的可能分区。我正在使用 CosmosDB .NetCore SDK。目前在约 6 千个分区中有约 17 万个文档。
我有一些功能需要通过 "SubId" 从集合中检索文档,但我不知道主键,这意味着我不知道分区键。不幸的是,我无法更改此功能以使用主键,因为它的依赖项是无法修改的遗留系统。
发生的事情是,我成功创建了一个新文档,然后在某个时候我需要使用 "SubId" 查询该文档。这是在 C# 中完成的,如下所示:
public async Task<DocumentModel> GetBySubId(string subId)
{
var collectionId = _cosmosClient.CollectionId;
var query = $@"SELECT * FROM {collectionId} c
WHERE ARRAY_CONTAINS(c.ArrayOfObjects, {{'SubId': '{subId}'}}, true)";
var feedOptions = new FeedOptions { EnableCrossPartitionQuery = true };
var docQuery = _cosmosClient.Client.CreateDocumentQuery(
_collectionUri,
query,
feedOptions)
.AsDocumentQuery();
var executedQuery = await docQuery.ExecuteNextAsync<DocumentModel>();
if (executedQuery.Count == 0)
{
return null;
}
return executedQuery.FirstOrDefault();
}
有时查询成功有时不成功,我 return 为空,然后从我的控制器我 return 一个 404。
为什么这很奇怪是因为如果我检查数据库并且 运行 直接查询文档就在那里并且实际上并没有丢失,但是由于某种原因当我使用 SDK 从 C# 查询时它找不到文档。我还有其他功能可以使用主键(现在意味着我有分区键)和 SubId 进行查询,并且工作正常。只有当我使用 SubId 本身查询时(没有分区键)它找不到文档。
鉴于以上情况,我认为这与没有分区键的查询有关。在没有分区键的情况下查询时我遗漏了什么?
我目前尝试的是将 database consistency 从 Eventual 设置为 Strong。这似乎没有任何区别。
What I've tried at the moment is setting the database consistency from Eventual to Strong. This doesn't seem to make any difference.
由此 document,Strong
级别一致性保证返回项目的最新提交版本。根据你的描述,你测试的环境不是高并发读操作。所以,我认为这与一致性水平无关。
Sometimes it queries successfully sometimes it doesn't and I return null, then from my controller I return a 404.
根据我的经验,由于吞吐量瓶颈,这个问题反复无常。查询分区集合时需要提供分区键。但是,您不知道分区键,只有在您设置示例代码中已经存在的 EnableCrossPartitionQuery = true
后才能完成。然后您的查询将跨越整个分区,直到找到特定文档。另外,array_contains
算子增加了查询的负担。
Cosmos DB 查询受吞吐量设置限制,不会覆盖整个数据库 endlessly.Please 请参阅此 document。
由于您现在无法调整您的分区策略,我建议您增加吞吐量设置来检查问题。
我来自 CosmosDB 工程团队。
您提到的行为可能是因为有时查询无法在一次继续中完成执行。请确保查询通过耗尽延续来完成执行。您可以在此处找到示例:https://docs.microsoft.com/en-us/azure/cosmos-db/performance-tips#throughput。在 IDocumentQuery.HasMoreResults 设置为 false 之前,查询执行不会被视为完成。