在Cassandra中根据日期时间查询列

时间:2012-03-21 09:48:27

标签: cassandra hector

我们正在尝试根据以下结构(例如日期时间,日期时间,整数)从CF创建/查询信息

e.g.
03-22-2012 10.00, 03-22-2012 10.30 100
03-22-2012 10.30, 03-22-2012 11.00 50
03-22-2012 11.00, 03-22-2012 11.30 200

如何在Cassandra中对上述结构进行建模,并通过Hector执行以下查询。

select * from <CF> where datetime1 > 03-22-2012 10.00 and datetime2 < 03-22-2012 10.30
select * from <CF> where datetime1 > 03-22-2012 10.00 and datetime2 < 03-22-2012 11.00
select * from <CF> where datetime = 03-22-2012 (i.e. for the entire day)

2 个答案:

答案 0 :(得分:2)

这是在Cassandra中处理日期和时间的一个很好的介绍:Basic Time Series with Cassandra

简而言之,使用时间戳(或v1 UUID)作为列名,并将比较器设置为LongType(或TimeUUIDType),以便按时间顺序排序列。然后很容易在两个时间点之间获得一片数据。

您的问题并不完全清楚,但如果您希望获得在一天中给定时间范围内发生的所有事件而不考虑日期,那么您将需要以不同方式构建数据。在这种情况下,列名称可以是CompositeType(LongType,AsciiType),其中第一个组件是正常时间戳mod 86400(一天中的秒数),第二个组件是日期或其他随时间变化的内容,像一个完整的时间戳。在这种情况下,您还需要分解行,可能每小时都有不同的行。

答案 1 :(得分:0)

不幸的是,Cassandra只有一个色谱柱系列无法轻松实现这一目标。问题是你想要cassandra根据两个不同的东西进行排序:datetime1和datetime2。

显而易见的结构是让您的Columns为Composite类型的Composite(TimeUUID,TimeUUID,Integer)。在这种情况下,它们将按datetime1排序,然后按datetime2排序,然后整数。

但是你总是得到基于datetime1而不是datetime2的订购(尽管如果两个条目具有相同的datetime1,那么它将根据datetime2对这些条目进行排序)。

可能的解决方法是让两个列族具有重复数据(或者每个逻辑行实际上有两行)。插入数据的一行(datetime1:datetime2:整数)和插入数据的另一行(datetime2:datetime1:integer)。然后,您可以对这两行执行multigetslice操作,并在将数据交给调用者之前合并数据:

final MultigetSliceQuery<String, Composite, String> query = HFactory.createMultigetSliceQuery(keyspace,
    StringSerializer.get(),
    CompositeSerializer.get(),
    StringSerializer.get());

query.setColumnFamily("myColumnFamily");
startQuery.setKeys("myRow.arrangedByDateTime1", "myRow.arrangedByDateTime2");
startQuery.setRange(new Composite(startTime), new Composite(endTime), false, Integer.MAX_VALUE);

final QueryResult<Rows<String,Composite,String>> queryResult = query.execute();
final Rows<String,Composite,String> rows = queryResult.get();