使用 SQL 的 Cosmos DB 查询在数据资源管理器中 运行 时有效,但在使用 C# DocumentClient 执行时无效
Cosmos DB query using SQL works when running in Data explorer but not when executed with the C# DocumentClient
我有一个查询,旨在统计特定类型的新文档和过时文档的数量。
考虑到我尝试在一个查询中获取多个类型的计数,很有可能应该重写查询并且新版本在使用 C# 时可以按预期工作。
如果我 运行 使用 "New SQL Query" 在 Cosmos DB 数据资源管理器中查询,但是当 运行 使用 2.2.2
和 2.8.1
(升级到最新版本)Microsoft.Azure.DocumentDB.Core
nuget 包中的 DocumentClient 版本它没有。
给出以下文档:
数据
[{
"PartitionKey": "partition",
"SomeKey": "foo",
"Type": "DocumentType",
"Value": "1",
"StaleAfterThis": 101
},
{
"PartitionKey": "partition",
"SomeKey": "bar",
"Type": "DocumentType",
"Value": "2",
"StaleAfterThis": 90
},
{
"PartitionKey": "partition",
"SomeKey": "bar",
"Type": "DocumentType",
"Value": "3",
"StaleAfterThis": 500
},
{
"PartitionKey": "partition",
"SomeKey": "foo",
"Type": "DocumentType",
"Value": "4",
"StaleAfterThis": 500
}]
以及以下查询:
查询
SELECT
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'foo' AND c.PartitionKey = 'partition' AND c.StaleAfterThis < 100)) as StaleFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'foo' AND c.PartitionKey = 'partition' AND c.StaleAfterThis >= 100)) as FreshFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'bar' AND c.PartitionKey = 'partition' AND c.StaleAfterThis < 100)) as StaleBarCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'bar' AND c.PartitionKey = 'partition' AND c.StaleAfterThis >= 100)) as FreshBarCount
FROM c
WHERE
c.Type = 'DocumentType' AND
c.PartitionKey = 'partition'
当 运行在数据资源管理器的基于 Web 的查询编辑器中执行此查询时,结果符合预期。
[
{
"StaleFooCount": 0,
"FreshFooCount": 1,
"StaleBarCount": 1,
"FreshBarCount": 1
}
]
如果我使用 C# 和 DocumentClient 尝试相同的查询,所有值都是 0。返回动态结果和类型化结果时都是这种情况。
C#键入的查询示例
var queryOptions = new FeedOptions { MaxItemCount = 1 };
var queryText =
@"SELECT
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@foo' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis < @staleAfterThis)) as StaleFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@foo' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis >= @staleAfterThis)) as FreshFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@bar' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis < @staleAfterThis)) as StaleBarCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@bar' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis >= @staleAfterThis)) as FreshBarCount
FROM c
WHERE
c.Type = 'DocumentType' AND
c.PartitionKey = '@partitionKey'";
var queryParameters = new SqlParameterCollection
{
new SqlParameter("@partitionKey", "partition"),
new SqlParameter("@foo", FooBarEnum.Foo.ToString()),
new SqlParameter("@bar", FooBarEnum.Bar.ToString()),
new SqlParameter("@staleAfterThis", 100)
};
var sqlQuerySpec = new SqlQuerySpec(queryText, queryParameters);
var query = _client.CreateDocumentQuery<TempResult>(_collectionLink, sqlQuerySpec, queryOptions).AsDocumentQuery();
var totalStaleDocuments = new TempResult();
while (query.HasMoreResults)
{
foreach (var result in await query.ExecuteNextAsync<TempResult>())
{
totalStaleDocuments.FreshFooCount += result.FreshFooCount;
totalStaleDocuments.StaleFooCount += result.StaleFooCount;
totalStaleDocuments.FreshBarCount += result.FreshBarCount;
totalStaleDocuments.StaleBarCount += result.StaleBarCount;
}
}
public class TempResult
{
public int StaleFooCount { get; set; }
public int FreshFooCount { get; set; }
public int StaleBarCount { get; set; }
public int FreshBarCount { get; set; }
}
预期结果:
[
{
"StaleFooCount": 0,
"FreshFooCount": 1,
"StaleBarCount": 1,
"FreshBarCount": 1
}
]
使用C#执行查询时的结果:
[
{
"StaleFooCount": 0,
"FreshFooCount": 0,
"StaleBarCount": 0,
"FreshBarCount": 0
}
]
你的 C# 查询不一样。在您的门户查询中,您正在做 c.SomeKey = 'foo'
,而在 C# 中,您正在做 c.Type = '@foo'
最后,从查询参数中删除 '
,如下所示:
var queryText =
@"SELECT
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = @foo AND c.PartitionKey = @partitionKey AND c.StaleAfterThis < @staleAfterThis)) as StaleFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = @foo AND c.PartitionKey = @partitionKey AND c.StaleAfterThis >= @staleAfterThis)) as FreshFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = @bar AND c.PartitionKey = @partitionKey AND c.StaleAfterThis < @staleAfterThis)) as StaleBarCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = @bar AND c.PartitionKey = @partitionKey AND c.StaleAfterThis >= @staleAfterThis)) as FreshBarCount
FROM c
WHERE
c.Type = 'DocumentType' AND
c.PartitionKey = @partitionKey";
我有一个查询,旨在统计特定类型的新文档和过时文档的数量。
考虑到我尝试在一个查询中获取多个类型的计数,很有可能应该重写查询并且新版本在使用 C# 时可以按预期工作。
如果我 运行 使用 "New SQL Query" 在 Cosmos DB 数据资源管理器中查询,但是当 运行 使用 2.2.2
和 2.8.1
(升级到最新版本)Microsoft.Azure.DocumentDB.Core
nuget 包中的 DocumentClient 版本它没有。
给出以下文档:
数据
[{
"PartitionKey": "partition",
"SomeKey": "foo",
"Type": "DocumentType",
"Value": "1",
"StaleAfterThis": 101
},
{
"PartitionKey": "partition",
"SomeKey": "bar",
"Type": "DocumentType",
"Value": "2",
"StaleAfterThis": 90
},
{
"PartitionKey": "partition",
"SomeKey": "bar",
"Type": "DocumentType",
"Value": "3",
"StaleAfterThis": 500
},
{
"PartitionKey": "partition",
"SomeKey": "foo",
"Type": "DocumentType",
"Value": "4",
"StaleAfterThis": 500
}]
以及以下查询:
查询
SELECT
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'foo' AND c.PartitionKey = 'partition' AND c.StaleAfterThis < 100)) as StaleFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'foo' AND c.PartitionKey = 'partition' AND c.StaleAfterThis >= 100)) as FreshFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'bar' AND c.PartitionKey = 'partition' AND c.StaleAfterThis < 100)) as StaleBarCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'bar' AND c.PartitionKey = 'partition' AND c.StaleAfterThis >= 100)) as FreshBarCount
FROM c
WHERE
c.Type = 'DocumentType' AND
c.PartitionKey = 'partition'
当 运行在数据资源管理器的基于 Web 的查询编辑器中执行此查询时,结果符合预期。
[
{
"StaleFooCount": 0,
"FreshFooCount": 1,
"StaleBarCount": 1,
"FreshBarCount": 1
}
]
如果我使用 C# 和 DocumentClient 尝试相同的查询,所有值都是 0。返回动态结果和类型化结果时都是这种情况。
C#键入的查询示例
var queryOptions = new FeedOptions { MaxItemCount = 1 };
var queryText =
@"SELECT
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@foo' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis < @staleAfterThis)) as StaleFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@foo' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis >= @staleAfterThis)) as FreshFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@bar' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis < @staleAfterThis)) as StaleBarCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@bar' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis >= @staleAfterThis)) as FreshBarCount
FROM c
WHERE
c.Type = 'DocumentType' AND
c.PartitionKey = '@partitionKey'";
var queryParameters = new SqlParameterCollection
{
new SqlParameter("@partitionKey", "partition"),
new SqlParameter("@foo", FooBarEnum.Foo.ToString()),
new SqlParameter("@bar", FooBarEnum.Bar.ToString()),
new SqlParameter("@staleAfterThis", 100)
};
var sqlQuerySpec = new SqlQuerySpec(queryText, queryParameters);
var query = _client.CreateDocumentQuery<TempResult>(_collectionLink, sqlQuerySpec, queryOptions).AsDocumentQuery();
var totalStaleDocuments = new TempResult();
while (query.HasMoreResults)
{
foreach (var result in await query.ExecuteNextAsync<TempResult>())
{
totalStaleDocuments.FreshFooCount += result.FreshFooCount;
totalStaleDocuments.StaleFooCount += result.StaleFooCount;
totalStaleDocuments.FreshBarCount += result.FreshBarCount;
totalStaleDocuments.StaleBarCount += result.StaleBarCount;
}
}
public class TempResult
{
public int StaleFooCount { get; set; }
public int FreshFooCount { get; set; }
public int StaleBarCount { get; set; }
public int FreshBarCount { get; set; }
}
预期结果:
[
{
"StaleFooCount": 0,
"FreshFooCount": 1,
"StaleBarCount": 1,
"FreshBarCount": 1
}
]
使用C#执行查询时的结果:
[
{
"StaleFooCount": 0,
"FreshFooCount": 0,
"StaleBarCount": 0,
"FreshBarCount": 0
}
]
你的 C# 查询不一样。在您的门户查询中,您正在做 c.SomeKey = 'foo'
,而在 C# 中,您正在做 c.Type = '@foo'
最后,从查询参数中删除 '
,如下所示:
var queryText =
@"SELECT
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = @foo AND c.PartitionKey = @partitionKey AND c.StaleAfterThis < @staleAfterThis)) as StaleFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = @foo AND c.PartitionKey = @partitionKey AND c.StaleAfterThis >= @staleAfterThis)) as FreshFooCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = @bar AND c.PartitionKey = @partitionKey AND c.StaleAfterThis < @staleAfterThis)) as StaleBarCount,
SUM((SELECT VALUE Count(1) WHERE c.SomeKey = @bar AND c.PartitionKey = @partitionKey AND c.StaleAfterThis >= @staleAfterThis)) as FreshBarCount
FROM c
WHERE
c.Type = 'DocumentType' AND
c.PartitionKey = @partitionKey";