按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的最新读数。