我有一个Azure表作为事件日志。我需要以最有效的方式来读取表格底部以检索最新的条目。
最有效的方法是什么?
答案 0 :(得分:2)
首先,我建议您根据UTC标记建立分区键。您可以通过从最新到最旧订购所有安心的方式来执行此操作。
然后,如果你想得到你可以说100个最新日志,你只需要调用(假设查询是IQueryable来自你最喜欢的客户端 - 我们使用Lucifure Stash):query.Take(100);
如果你想获取特定时期的实体,你可以写:query.Where(x => x.PartitionKey< = value);或类似的东西。
必须根据构造分区键值的方式构造“value”变量。
答案 1 :(得分:0)
假设您想要获取最近15分钟的数据,请尝试以下伪代码:
DateTime toDateTime = DateTime.UtcNow;
DateTime fromDateTime = toDateTime.AddMinutes(-15);
string myPartitionKeyFrom = fromDateTime.ToString("yy-MM");
string myPartitionKeyTo = toDateTime.ToString("yy-MM");
string query = "";
if (myPartitionKeyFrom.Equals(myPartitionKeyTo))//In case both time periods fall in same month, then we can directly hit that partition.
{
query += "(PartitionKey eq '" + myPartitionKeyFrom + "') ";
}
else // Otherwise we would need to do a greater than and lesser than stuff.
{
query += "(PartitionKey ge '" + myPartitionKeyFrom + "' and PartitionKey le '" + myPartitionKeyTo + "') ";
}
query += "and (RowKey ge '" + fromDateTime.ToString() + "' and RowKey le '" + toDateTime.ToString() + "')";
答案 2 :(得分:0)
如果您想获取最新的'n'个条目,那么您需要稍微修改您的PartitionKey和RowKey值,以便将最新的条目推送到表格的顶部。
为此,您需要使用DateTime.MaxValue.Subtract(DateTime.UtcNow).Ticks;
而不是DateTime.UtcNow来计算两个键。
答案 3 :(得分:0)
Microsoft提供了SemanticLogging框架,该框架具有log to Azure Table的特定接收器。
如果查看库代码,它会根据日期时间生成分区键(按相反顺序):
static string GeneratePartitionKeyReversed(DateTime dateTime)
{
dateTime = dateTime.AddMinutes(-1.0);
return GetTicksReversed(
new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, 0));
}
static string GetTicksReversed(DateTime dateTime)
{
return (DateTime.MaxValue - dateTime.ToUniversalTime())
.Ticks.ToString("d19", (IFormatProvider)CultureInfo.InvariantCulture);
}
因此,您可以在应用程序中实现相同的逻辑来构建分区密钥。
如果要检索特定日期范围的日志,可以编写如下查询:
var minDate = GeneratePartitionKeyReversed(DateTime.UtcNow.AddHours(-2));
var maxDate = GeneratePartitionKeyReversed(DateTime.UtcNow.AddHours(-1));
// Get the cloud table
var cloudTable = GetCloudTable();
// Build the query
IQueryable<DynamicTableEntity> query = cloudTable.CreateQuery<DynamicTableEntity>();
// condition for max date
query = query.Where(a => string.Compare(a.PartitionKey, maxDate,
StringComparison.Ordinal) >= 0);
// condition for min date
query = query.Where(a => string.Compare(a.PartitionKey, minDate,
StringComparison.Ordinal) <= 0);3