Java 我应该如何在Cassandra中存储日期间隔?
我正在开发一个存储传感器测量值的应用程序。有时,传感器会发送错误的测量值(例如,测量值超出范围)。我们不希望单独保留每个测量误差,但我们希望保留关于这些误差的统计信息,例如传感器id、第一个误差的日期、最后一个误差的日期,以及其他信息,如连续误差的数量,我将在这里省略这些信息 下面是“ErrorStatistic”类的简化版本: 我目前使用Hector将这些错误统计数据保存如下:Java 我应该如何在Cassandra中存储日期间隔?,java,nosql,cassandra,Java,Nosql,Cassandra,我正在开发一个存储传感器测量值的应用程序。有时,传感器会发送错误的测量值(例如,测量值超出范围)。我们不希望单独保留每个测量误差,但我们希望保留关于这些误差的统计信息,例如传感器id、第一个误差的日期、最后一个误差的日期,以及其他信息,如连续误差的数量,我将在这里省略这些信息 下面是“ErrorStatistic”类的简化版本: 我目前使用Hector将这些错误统计数据保存如下: private void persistErrorStatistic(ErrorStatistic errorSta
private void persistErrorStatistic(ErrorStatistic errorStatistic) {
Mutator<String> mutator = HFactory.createMutator(keyspace, StringSerializer.get());
String rowKey = errorStatistic.getSensorId();
String columnName = errorStatistic.getStartDate().toString(YYYY_MM_DD_FORMATTER);
byte[] value = serialize(errorStatistic);
HColumn<String, byte[]> column = HFactory.createColumn(columnName, value, StringSerializer.get(), BytesArraySerializer.get());
mutator.addInsertion(rowKey, COLUMN_FAMILY, column);
mutator.execute();
}
private static final DateTimeFormatter YYYY_MM_DD_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
如果我向卡桑德拉询问日期:
- 2012-08-04T10:00Z-->它应该返回第一个ErrorStatistic
- 2012-09-04T00:00Z-->此时应返回没有错误
- 2014-01-03T00:00Z-->它应该返回最后一个ErrorStatistic(因为它是开放式的)
编辑:添加以下内容是为了回应Joost的建议,即我应该关注我感兴趣的查询类型 我将有两种类型的查询:
- 第一,正如您所猜测的,是列出给定传感器和时间范围的所有错误统计信息。这似乎相对容易。我唯一的问题是,当ErrorStatistics在我感兴趣的时间范围之前开始时(例如,我查询4月份的所有错误,我希望我的查询也返回ErrorStatistics[2012-03-29:2012-04-02])
- 第二个问题似乎更难回答。我想查找给定传感器和日期的错误统计信息,其间隔包含给定日期,或其
位于给定日期之前,且带有空startDate
(这意味着我们仍然收到此传感器的错误)。我不知道如何有效地做到这一点。我可以加载给定传感器的所有错误统计信息,然后用Java检查间隔。。。但如果可能的话,我想避免这种情况。我想我希望Cassandra从一个给定的日期开始,向后看,直到它找到第一个错误统计数据,并且在给定的日期(如果有的话)之前有一个endDate
,然后加载它并在Java中检查它的startDate
是否为endDate
或者在给定的日期之后。但我不知道这是否可能,以及效率有多高null
添加(2013-9-5):很高兴知道的是Cassandra在单个分区键的范围内对数据进行排序。这是非常有用的。例如,如果您将表格定义为:
create table SensorByDate
(
sensor_id uuid,
start_date datetime,
end_date datetime,
measurement int
primary key (sensor_id, start_date)
)
with clustering order by (start_time DESC);
在本例中,sensor_id是分区键,并确定该行存储在哪个节点上。开始日期是组合键中的第二项,决定排序顺序
要获取此表中某个开始日期之后的第一个度量值,可以制定如下查询
select * from SensorByDate
where sensor_id = ? and start_date < ? limit 1
从SensorByDate中选择*
其中传感器_id=?和开始日期<?限制1
我喜欢您使用“每查询一个表”方法设计模式的想法。作为一个新的Cassandra用户,需要一些时间来适应它。我将更新我的问题,以指定我感兴趣的两种查询类型。
create table SensorByDate
(
sensor_id uuid,
start_date datetime,
end_date datetime,
measurement int
primary key (sensor_id, start_date)
)
with clustering order by (start_time DESC);
select * from SensorByDate
where sensor_id = ? and start_date < ? limit 1