按Cassandra中的时间戳订购最新记录
我正在尝试显示传感器列表中的最新值。列表还应按时间戳排序 我尝试了两种不同的方法。我将传感器的更新时间包含在主键中:按Cassandra中的时间戳订购最新记录,cassandra,time-series,Cassandra,Time Series,我正在尝试显示传感器列表中的最新值。列表还应按时间戳排序 我尝试了两种不同的方法。我将传感器的更新时间包含在主键中: CREATE TABLE sensors ( customerid int, sensorid int, changedate timestamp, value text, PRIMARY KEY (customerid, changedate) ) WITH CLUSTERING ORDER BY (changedate DESC);
CREATE TABLE sensors (
customerid int,
sensorid int,
changedate timestamp,
value text,
PRIMARY KEY (customerid, changedate)
) WITH CLUSTERING ORDER BY (changedate DESC);
然后我可以选择如下列表:
select * from sensors where customerid=0 order by changedate desc;
其结果是:
customerid | changedate | sensorid | value
------------+--------------------------+----------+-------
0 | 2015-07-10 12:46:53+0000 | 1 | 2
0 | 2015-07-10 12:46:52+0000 | 1 | 1
0 | 2015-07-10 12:46:52+0000 | 0 | 2
0 | 2015-07-10 12:46:26+0000 | 0 | 1
问题是,我不仅得到了最新的结果,还得到了所有的旧值
如果我从主键中删除changedate,则选择将同时失败
InvalidRequest: code=2200 [Invalid query] message="Order by is currently only supported on the clustered columns of the PRIMARY KEY, got changedate"
更新传感器值也不是选项:
update overview set changedate=unixTimestampOf(now()), value = '5' where customerid=0 and sensorid=0;
InvalidRequest: code=2200 [Invalid query] message="PRIMARY KEY part changedate found in SET part"
此操作失败,因为changedate是主键的一部分
是否有任何可能的方法仅存储每个传感器的最新值,并按时间戳对表格进行排序
编辑:
与此同时,我尝试了另一种方法,只存储最新的值
我使用了这个模式:
CREATE TABLE sensors (
customerid int,
sensorid int,
changedate timestamp,
value text,
PRIMARY KEY (customerid, sensorid, changedate)
) WITH CLUSTERING ORDER BY (changedate DESC);
在插入最新值之前,我将删除所有旧值
DELETE FROM sensors WHERE customerid=? and sensorid=?;
但是这失败了,因为changedate
不是WHERE子句的一部分
问题是,我不仅得到了最新的结果,还得到了所有的旧值
由于您是按DESC的群集顺序存储的,因此获取最新记录总是非常容易的,您只需在查询中添加“限制”,即:
select * from sensors where customerid=0 order by changedate desc limit 10;
将返回最多10条具有最高更改日期的记录。即使您使用的是limit,您仍然可以保证获得最新的记录,因为您的数据是按这种方式排序的
如果我从主键中删除changedate,则选择将同时失败
InvalidRequest: code=2200 [Invalid query] message="Order by is currently only supported on the clustered columns of the PRIMARY KEY, got changedate"
这是因为您不能对不是集群键(主键的第二部分)的列进行排序,除非可能使用第二索引,我不建议这样做
更新传感器值也不是选项
更新查询失败,因为在“set”中包含部分主键是不合法的。要完成这项工作,您只需更新查询,将changedate包含在where子句中,即:
update overview set value = '5' and sensorid = 0 where customerid=0 and changedate=unixTimestampOf(now())
是否有任何可能的方法仅存储每个传感器的最新值,并按时间戳对表格进行排序
可以通过创建一个名为“latest_sensor_data”的单独表来完成此操作,该表具有相同的表定义,主键除外。主键现在将是“customerid,sensorid”,因此每个传感器只能有一条记录。创建单独表的过程称为,这是一种常用模式,特别是在Cassandra数据建模中。当您插入传感器数据时,您现在可以将数据同时插入“传感器”和“最新传感器数据”
CREATE TABLE latest_sensor_data (
customerid int,
sensorid int,
changedate timestamp,
value text,
PRIMARY KEY (customerid, sensorid)
);
在cassandra中,将引入3.0,这将使这变得不必要,因为您可以使用物化视图来完成这项工作
现在执行以下查询:
select * from latest_sensor_data where customerid=0
将为该客户提供每个传感器的最新值
我建议将“传感器”重命名为“传感器数据”或“传感器历史”,以便更清楚地了解数据内容。此外,您应该将主键更改为“customerid、changedate、sensorid”,因为这样可以在同一日期拥有多个传感器(这似乎是可能的)。您的第一种方法看起来很合理。如果您将“限制1”添加到查询中,您将只获得最新的结果,或限制2以查看最新的2个结果,以此类推
如果要自动从表中删除旧值,可以在执行插入时为数据点指定TTL(生存时间)。因此,如果您想将数据点保留10天,可以在insert语句中添加“USING TTL 864000”。或者可以为整个表设置默认TTL 另一个注意事项是,如果您想要比最新值(即最后10个值)更多的值,则会变得更困难。在C*2.2中,您可以使用用户定义的聚合,让cassandra为您的传感器表按客户获取每个传感器的10个“最新”值。你也可以偶尔考虑使用spark cassandra连接器来计算。你建议的问题是,我失去了按
changedate
排序的能力。我建议使用两个表,一个表在changedate上有一个聚类键(“sensor\u history”表)另一个群集在sensorid上。我不能在这里使用TTL,因为没有保证的时间跨度,传感器报告值。它可能会沉默数天、数周甚至数月。但我仍然需要保留最新的值。我认为OP希望每个sensorID都是最新的。这似乎是检索每个组问题中最后一条记录的经典方法。即获取每个传感器ID的最新读数。