在 RowKey 值范围内使用 Azure Table 的词法过滤
Using Lexical Filtering of Azure Table on range of RowKey values
问题:没有返回结果。
我正在使用以下代码从只有 100 行左右的分区中获取一系列对象:
var rangeQuery = new TableQuery<StorageEntity>().Where(
TableQuery.CombineFilters(
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey),
TableOperators.And,
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThanOrEqual, from)
),
TableOperators.And,
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThanOrEqual, to)
)
);
var results = table.ExecuteQuery(rangeQuery);
foreach (StorageEntity entity in results)
{
storageEntities.Add(entity);
}
注意:我如何组合这 3 个术语似乎并不重要,不会返回任何结果。我期待的一个例子是这个 (partitionKey, rowKey):
"10005678", "PL7NR_201503170900"
范围过滤器代码生成此表达式:
((PartitionKey eq '10005678') and (RowKey ge 'PL7NR_201503150000'))
and (RowKey lt 'PL7NR_201504082359')
但我也尝试过这个(出于性能原因,这是我的首选方法,即分区扫描):
(PartitionKey eq '10005678') and ((RowKey ge 'PL7NR_201503150000') and
(RowKey lt 'PL7NR_201504082359'))
我的理解是 Table 存储执行词法搜索,因此这些行键应该包含一个范围,其中包含具有以下键的行:
"10005678", "PL7NR_201503170900"
我的理解有什么根本性的错误吗?
感谢您的关注。
更新:由于 Gaurav 的回答更新了问题。上面的代码隐式处理连续标记(即 foreach 循环)并且分区中只有 100 个左右的项目,所以我不认为连续标记是一个问题。
我试过从键中删除下划线 ('_'),甚至尝试从 rowKey 中移动前缀并将其作为后缀添加到 partitionKey。
NOTE: This is all running on my local machine using storage emulation.
来自Query Timeout and Pagination
:
A query against the Table service may return a maximum of 1,000 items
at one time and may execute for a maximum of five seconds. If the
result set contains more than 1,000 items, if the query did not
complete within five seconds, or if the query crosses the partition
boundary, the response includes headers which provide the developer
with continuation tokens to use in order to resume the query at the
next item in the result set. Continuation token headers may be
returned for a Query Tables operation or a Query Entities operation.
请检查您是否回复 Continuation Token
。
现在开始您的过滤表达式:
((PartitionKey eq '10005678') and (RowKey ge 'PL7NR_201503150000'))
and (RowKey lt 'PL7NR_201504082359')
这个绝对是在做一个Full Table Scan
因为(RowKey lt 'PL7NR_201504082359')
本身就是一个子句。为了执行这个特定的部分,它基本上从 table 的顶部开始,并在不考虑 PartitionKey 的情况下找出 RowKey < 'PL7NR_201504082359'
的实体。
(PartitionKey eq '10005678') and ((RowKey ge 'PL7NR_201503150000') and
(RowKey lt 'PL7NR_201504082359'))
这个正在执行 Partition Scan
如果指定分区中的数据过多或查询时间超过 5 秒,您可能无法返回结果如上所述执行。
因此,请检查您的查询是否返回任何延续标记,如果没有返回任何实体,则使用它们获取下一组实体。
一些您可能会觉得有用的资源:
- 如何充分利用 Windows Azure Tables:http://blogs.msdn.com/b/windowsazurestorage/archive/2010/11/06/how-to-get-most-out-of-windows-azure-tables.aspx
- Azure 存储Table 设计指南:设计可扩展和高性能Tables:http://azure.microsoft.com/en-us/documentation/articles/storage-table-design-guide/
问题:没有返回结果。
我正在使用以下代码从只有 100 行左右的分区中获取一系列对象:
var rangeQuery = new TableQuery<StorageEntity>().Where(
TableQuery.CombineFilters(
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey),
TableOperators.And,
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThanOrEqual, from)
),
TableOperators.And,
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThanOrEqual, to)
)
);
var results = table.ExecuteQuery(rangeQuery);
foreach (StorageEntity entity in results)
{
storageEntities.Add(entity);
}
注意:我如何组合这 3 个术语似乎并不重要,不会返回任何结果。我期待的一个例子是这个 (partitionKey, rowKey):
"10005678", "PL7NR_201503170900"
范围过滤器代码生成此表达式:
((PartitionKey eq '10005678') and (RowKey ge 'PL7NR_201503150000')) and (RowKey lt 'PL7NR_201504082359')
但我也尝试过这个(出于性能原因,这是我的首选方法,即分区扫描):
(PartitionKey eq '10005678') and ((RowKey ge 'PL7NR_201503150000') and (RowKey lt 'PL7NR_201504082359'))
我的理解是 Table 存储执行词法搜索,因此这些行键应该包含一个范围,其中包含具有以下键的行:
"10005678", "PL7NR_201503170900"
我的理解有什么根本性的错误吗?
感谢您的关注。
更新:由于 Gaurav 的回答更新了问题。上面的代码隐式处理连续标记(即 foreach 循环)并且分区中只有 100 个左右的项目,所以我不认为连续标记是一个问题。
我试过从键中删除下划线 ('_'),甚至尝试从 rowKey 中移动前缀并将其作为后缀添加到 partitionKey。
NOTE: This is all running on my local machine using storage emulation.
来自Query Timeout and Pagination
:
A query against the Table service may return a maximum of 1,000 items at one time and may execute for a maximum of five seconds. If the result set contains more than 1,000 items, if the query did not complete within five seconds, or if the query crosses the partition boundary, the response includes headers which provide the developer with continuation tokens to use in order to resume the query at the next item in the result set. Continuation token headers may be returned for a Query Tables operation or a Query Entities operation.
请检查您是否回复 Continuation Token
。
现在开始您的过滤表达式:
((PartitionKey eq '10005678') and (RowKey ge 'PL7NR_201503150000')) and (RowKey lt 'PL7NR_201504082359')
这个绝对是在做一个Full Table Scan
因为(RowKey lt 'PL7NR_201504082359')
本身就是一个子句。为了执行这个特定的部分,它基本上从 table 的顶部开始,并在不考虑 PartitionKey 的情况下找出 RowKey < 'PL7NR_201504082359'
的实体。
(PartitionKey eq '10005678') and ((RowKey ge 'PL7NR_201503150000') and (RowKey lt 'PL7NR_201504082359'))
这个正在执行 Partition Scan
如果指定分区中的数据过多或查询时间超过 5 秒,您可能无法返回结果如上所述执行。
因此,请检查您的查询是否返回任何延续标记,如果没有返回任何实体,则使用它们获取下一组实体。
一些您可能会觉得有用的资源:
- 如何充分利用 Windows Azure Tables:http://blogs.msdn.com/b/windowsazurestorage/archive/2010/11/06/how-to-get-most-out-of-windows-azure-tables.aspx
- Azure 存储Table 设计指南:设计可扩展和高性能Tables:http://azure.microsoft.com/en-us/documentation/articles/storage-table-design-guide/