查询 azure table 服务给出了不同的结果
Querying azure table service gives diffrent results
我正在尝试使用 Microsoft Azure Storage SDK 查询 azure table 存储。发送简单请求 returns 预期结果(类似于 https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-tables#retrieve-a-range-of-entities-in-a-partition )。但是当我发送一个像这样的更复杂的查询时:
(((((((((PartitionKey eq 'LOS-test1-20161218') or (PartitionKey eq 'SPA-test1-20161218')) or (PartitionKey eq 'LOS-test2-20161219')) or (PartitionKey eq 'SPA-test2-20161219')) or (PartitionKey eq 'SPA-test3-20161218')) or (PartitionKey eq 'LOS-test3-20161218')) or (PartitionKey eq 'SPA-test4-20161219')) or (PartitionKey eq 'LOS-test4-20161219')) or (PartitionKey eq 'SPA-test5-20161219')) or (PartitionKey eq 'LOS-test5-20161219')
我只得到了预期结果的一部分(三分之一)。同时,当我 运行 使用 Microsoft Azure 存储资源管理器进行此查询时,我得到了正确的数据。
为什么会这样?
private string GenerateFilterCondition(string s, string c, DateTime date)
{
return TableQuery.GenerateFilterCondition(
"PartitionKey", QueryComparisons.Equal,
s + "-" + c + "-" + date.ToString("yyyyMMdd"));
}
private List<SiteSpecificDataTableDataSet> GetSiteSpecificDataTableDataSet()
{
_connection.Open();
DateTime selectedDate = DateTime.Now.AddDays(-1);
TableQuery<DataEntity> tq = new TableQuery<DataEntity>().Where(GenerateFilterCondition("SPA", "test5", selectedDate));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("LOS", "test5", selectedDate));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("SPA", "test4", selectedDate.AddDays(1)));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("LOS", "test4", selectedDate.AddDays(1)));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("LOS", "test3", selectedDate));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("SPA", "test3", selectedDate));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("LOS", "test2", selectedDate.AddDays(1)));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("SPA", "test2", selectedDate.AddDays(1)));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("LOS", "test1", selectedDate.AddDays(1)));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("SPA", "test1", selectedDate.AddDays(1)));
IEnumerable<DataEntity> entities = _connection.QueryData(tq);
}
而 QueryData
看起来像:
IEnumerable<DataEntity> res;
List<DataEntity> queryResult = new List<DataEntity>();
CloudTableClient tableClient = _storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("data");
TableContinuationToken tct = null;
do
{
// Retrieve a segment (up to 1,000 entities).
TableQuerySegment<DataEntity> tableQueryResult = table.ExecuteQuerySegmentedAsync(query, tct).Result;
if (tableQueryResult.Results.Count == 0) break;
tct = tableQueryResult.ContinuationToken;
foreach (var result in tableQueryResult.Results)
{
queryResult.Add(result);
}
} while (tct != null);
res = queryResult;
你代码中的这个条件不正确:"if (tableQueryResult.Results.Count == 0) break",结果为空,你可能还需要继续查询。
正确的条件应该是:"if (tableQueryResult.ContinuationToken == null) break".
顺便说一句,强烈不建议在一个过滤器字符串中查询不同的分区键,因为根据 Azure Table 设计,它会导致整个 table 扫描,这在性能上很糟糕。您需要将查询拆分为多个(一次一个分区键)查询以获得更好的性能。
我正在尝试使用 Microsoft Azure Storage SDK 查询 azure table 存储。发送简单请求 returns 预期结果(类似于 https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-tables#retrieve-a-range-of-entities-in-a-partition )。但是当我发送一个像这样的更复杂的查询时:
(((((((((PartitionKey eq 'LOS-test1-20161218') or (PartitionKey eq 'SPA-test1-20161218')) or (PartitionKey eq 'LOS-test2-20161219')) or (PartitionKey eq 'SPA-test2-20161219')) or (PartitionKey eq 'SPA-test3-20161218')) or (PartitionKey eq 'LOS-test3-20161218')) or (PartitionKey eq 'SPA-test4-20161219')) or (PartitionKey eq 'LOS-test4-20161219')) or (PartitionKey eq 'SPA-test5-20161219')) or (PartitionKey eq 'LOS-test5-20161219')
我只得到了预期结果的一部分(三分之一)。同时,当我 运行 使用 Microsoft Azure 存储资源管理器进行此查询时,我得到了正确的数据。
为什么会这样?
private string GenerateFilterCondition(string s, string c, DateTime date)
{
return TableQuery.GenerateFilterCondition(
"PartitionKey", QueryComparisons.Equal,
s + "-" + c + "-" + date.ToString("yyyyMMdd"));
}
private List<SiteSpecificDataTableDataSet> GetSiteSpecificDataTableDataSet()
{
_connection.Open();
DateTime selectedDate = DateTime.Now.AddDays(-1);
TableQuery<DataEntity> tq = new TableQuery<DataEntity>().Where(GenerateFilterCondition("SPA", "test5", selectedDate));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("LOS", "test5", selectedDate));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("SPA", "test4", selectedDate.AddDays(1)));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("LOS", "test4", selectedDate.AddDays(1)));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("LOS", "test3", selectedDate));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("SPA", "test3", selectedDate));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("LOS", "test2", selectedDate.AddDays(1)));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("SPA", "test2", selectedDate.AddDays(1)));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("LOS", "test1", selectedDate.AddDays(1)));
tq = AddFilterORToTableQuery(tq.FilterString, GenerateFilterCondition("SPA", "test1", selectedDate.AddDays(1)));
IEnumerable<DataEntity> entities = _connection.QueryData(tq);
}
而 QueryData
看起来像:
IEnumerable<DataEntity> res;
List<DataEntity> queryResult = new List<DataEntity>();
CloudTableClient tableClient = _storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("data");
TableContinuationToken tct = null;
do
{
// Retrieve a segment (up to 1,000 entities).
TableQuerySegment<DataEntity> tableQueryResult = table.ExecuteQuerySegmentedAsync(query, tct).Result;
if (tableQueryResult.Results.Count == 0) break;
tct = tableQueryResult.ContinuationToken;
foreach (var result in tableQueryResult.Results)
{
queryResult.Add(result);
}
} while (tct != null);
res = queryResult;
你代码中的这个条件不正确:"if (tableQueryResult.Results.Count == 0) break",结果为空,你可能还需要继续查询。
正确的条件应该是:"if (tableQueryResult.ContinuationToken == null) break".
顺便说一句,强烈不建议在一个过滤器字符串中查询不同的分区键,因为根据 Azure Table 设计,它会导致整个 table 扫描,这在性能上很糟糕。您需要将查询拆分为多个(一次一个分区键)查询以获得更好的性能。