如何根据WRITETIME过滤Cassandra结果

Yur*_*rik 4 cql cassandra

我想得到值,其WRITETIME值比某个时间更新.我尝试了这个查询,但它失败了:

SELECT zoom,idx FROM tiles
WHERE zoom=5 AND writetime(tile) > maxTimeuuid('2015-01-01 00:05+0000')
ALLOW FILTERING;
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

SyntaxException: <ErrorMessage code=2000 [Syntax error in CQL query] 
    message="line 1:68 no viable alternative at input '(' (...and idx > 0 
    and [writetime](...)">
Run Code Online (Sandbox Code Playgroud)

对于此表:

CREATE TABLE tiles (
    zoom int,
    idx int,
    tile blob,
    PRIMARY KEY (zoom, idx)
) WITH COMPACT STORAGE
Run Code Online (Sandbox Code Playgroud)

Aar*_*ron 9

WRITETIME是用于显示特定列的写入时间的函数.它不是PRIMARY KEY的一部分,也不是索引,因此不能在WHERE子句中使用它.为了能够在编写特定(而不是列)时进行查询,您应该将其作为附加列添加到表中,作为第一个集群键:

CREATE TABLE tilesByLastWritten (
    zoom int,
    idx int,
    tile blob,
    lastwritten timeuuid,
    PRIMARY KEY (zoom, lastwritten, idx)
) WITH CLUSTERING ORDER BY (lastwritten DESC, idx ASC);
Run Code Online (Sandbox Code Playgroud)

现在这个查询将起作用:

aploetz@cqlsh:stackoverflow2> SELECT * FROM tilesByLastWritten 
    WHERE zoom=5 AND lastwritten > mintimeuuid('2015-07-02 08:30:00-0500');

 zoom | lastwritten                          | idx | tile
------+--------------------------------------+-----+------
    5 | 3a439c60-20bf-11e5-b9cb-21b264d4c94d |   1 | null

(1 rows)
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 不要使用该ALLOW FILTERING指令.基本上,这告诉Cassandra可以从所有节点中提取所有表的行,然后应用过滤器.
  • 不要COMPACT STORAGE在表创建上使用.这是专为人们将新的CQL3表转换为传统的Thrift引擎存储格式而设计的.如果你没有专门那个,那你就不应该使用它.
  • 我在我的示例中指定了CLUSTERING ORDER,以DESCending顺序对tiles表进行排序lastwritten.通常,基于时间序列的应用程序关心获取最新数据,因此这通常是有意义的.如果您不是这种情况,那么(默认)ASCending订单应该没问题.
  • 在我的示例中,我将其idx作为最后一个聚类键包含在内,主要用于唯一性.如果您发现自己必须为该列构建查询,则可能需要使用不同的查询表(使用重新排列的主键)来支持该列.

有关此领域的更多帮助,请阅读Patrick McFadin的时间序列数据建模入门.