繁体   English   中英

如何在 Azure 表存储中使用 RowKey 或时间戳检索最新记录

[英]How to retrieve latest record using RowKey or Timestamp in Azure Table storage

棘手的部分是RowKeystring ,它的值类似于Mon Nov 14 12:26:42 2016

我尝试使用Timestamp查询

var lowerlimit = DateTime.UtcNow; // its should be nearer to table timestamp data.
            TableQuery<TemperatureEntity> query2 = new TableQuery<TemperatureEntity>().Where(TableQuery.GenerateFilterConditionForDate("Timestamp", QueryComparisons.GreaterThanOrEqual,lowerlimit));
            var test = table.ExecuteQuery(query2);

我的实体.cs

  public class MyEntity : TableEntity
    {
        public MyEntity(string partitionKey, string rowKey)
        {
            this.PartitionKey = partitionKey;
            this.RowKey = rowKey;
        }

        public MyEntity() { }

        public Int64 DevideId { get; set; }

        public string RowKey { get; set; }
    }

//下面的查询给出了完整的数据Program.cs

// Retrieve the storage account from the connection string.
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
                CloudConfigurationManager.GetSetting("StorageConnectionString"));

            // Create the table client.
            CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

            // Create the CloudTable object that represents the "TemperatureData" table.
            CloudTable table = tableClient.GetTableReference("TemperatureData");

            // retrive data
            TableQuery<TemperatureEntity> query = new TableQuery<TemperatureEntity>();
            var data = table.ExecuteQuery(query);

在此处输入图片说明

尼奥,

如果您需要在分区中拥有最新条目,则对行键使用字符串日期时间不是一个好方法,因为表存储基于行键以升序存储实体。

如果在当前点您可以更改行键的值,请使用DateTime.UtcNow.Ticks

var invertedTimeKey = DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks

使用这种方法,在查询您的表时,您将能够获取对应于最新的 1 个条目。

如果您无法更改行键的值,则必须检索分区中的所有条目,这意味着将所有条目加载到内存中,然后使用时间戳对它们进行排序以检索最后一个。 如果您有很多条目,这绝对不是一个好方法。

var lastResult = results.OrderByDescending(r => r.Timestamp).FirstOrDefault();

Azure 表服务不支持Order By排序功能,因此对于当前设置,您唯一的选择是下载所有实体并在客户端按逆序对它们进行排序。 当表中的实体数量变大时,这显然不是最佳解决方案。

其他选项(这将需要您重新设计应用程序)是将日期/时间值转换为反向刻度:

var rowKey = (DateTime.MaxValue.Ticks - DateTimeValueForRowKey.Ticks).ToString("d19")

这将确保将最新的条目添加到表格的顶部而不是表格的底部。 要获取最新条目,您只需从表中获取第一个实体。

某些情况下可能运行良好的另一种方法是通过为您希望工作的值生成范围查询或一组范围查询来“巧妙地强制”表并立即将它们全部关闭.

在这种情况下,由于行键的格式为Mon Nov 14 12:26:42 2016 (并且假设 OP @neo 无法更改它),并且他们想要最新的结果,那么您可以获得前缀查询(仍然是字典范围查询)的良好性能,Azure 说它是最快的非精确查询类型

其次是范围查询,它使用PartitionKey并过滤一系列RowKey值以返回多个实体。 PartitionKey值标识特定分区, RowKey值标识该分区中实体的子集。 例如: $filter=PartitionKey eq 'Sales' and RowKey ge 'S' and RowKey lt 'T'

使这项工作的一个巧妙技巧是利用这一事实,即Mon Nov 14将仅是这些日期:

1977-11-14
1983-11-14
1988-11-14
1994-11-14
2005-11-14
2011-11-14
2016-11-14
2022-11-14
2033-11-14
2039-11-14
2044-11-14
etc

因此,简单地对Mon Nov 14进行前缀搜索将安全地返回隐含所需年份(2016 年)的记录,可能还有 1 或 2 年可以安全地在内存中排除,而不会对性能造成重大影响(例如 2011 年和 2022 年)。

请注意,如果您为PartitionKey提供确切的值(在这种情况下始终为"raspberrypi" ,Azure 仅使用真正的范围查询。 OP 的原始查询没有。

String partitionKeyFilter = TableQuery.GenerateFilterCondition(
    propertyName: "PartitionKey",
    operation   : QueryComparisons.Equal,
    givenValue  : "raspberrypi"
);

DateTime today = DateTime.UtcNow;
String todayPrefix = today.ToString( "ddd MMM dd", CultureInfo.InvariantCulture );

String rowKeyFilter = TableQuery.GenerateFilterCondition(
    propertyName: "RowKey",
    operation   : QueryComparisons.GreaterThan,
    givenValue  : todayPrefix 
);

TableQuery<TemperatureEntity> query = new TableQuery<TemperatureEntity>()
{
    FilterString = TableQuery.CombineFilters( partitionKeyFilter, TableOperators.And, rowKeyFilter );
}

List<TemperatureEntity> queryResults = table
    .ExecuteQuery( query )
    .Where( e => e.RowKey.EndsWith( today.ToString(" yyyy") ) ) // Filter current-year in the client.
    .ToList();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM