【问题标题】:How to filter Cassandra result based on WRITETIME如何根据 WRITETIME 过滤 Cassandra 结果
【发布时间】:2015-07-02 23:08:49
【问题描述】:

我想获取 WRITETIME 值比某个时间新的值。我试过这个查询,但它失败了:

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

我收到此错误:

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

对于这个表:

CREATE TABLE tiles (
    zoom int,
    idx int,
    tile blob,
    PRIMARY KEY (zoom, idx)
) WITH COMPACT STORAGE

【问题讨论】:

    标签: cassandra cql


    【解决方案1】:

    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);
    

    现在这个查询可以工作了:

    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)
    

    注意事项:

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

    如需这方面的更多帮助,请阅读 Patrick McFadin 的Getting Started With Timeseries Data Modeling

    【讨论】:

    • 谢谢布莱斯!大多数时候,我会以SELECT tile FROM tiles WHERE zoom=? AND idx=? 的形式进行查询(结果为 1 行)。更罕见的是,我会执行“SELECT idx, WRITETIME(tile) FROM tile WHERE zoom=? AND idx >= ? AND idx
    • @Yurik 在这种情况下,您的原始表应该可以很好地处理这些查询。但是,如果您确实想在上次写入时间之前进行查询,那么我建议您创建一个单独的表(类似于我上面描述的表)来支持该查询。
    • 如果您有一个不会随时间变化的简单表格,COMPACT STORAGE 似乎是个好主意...它使事情变得更快...更紧凑 (35%)。 blog.librato.com/posts/cassandra-compact-storage
    猜你喜欢
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 2018-10-10
    相关资源
    最近更新 更多