【问题标题】:Selecting timeuuid columns corresponding to a specific date选择与特定日期对应的 timeuuid 列
【发布时间】:2013-09-30 22:01:08
【问题描述】:

短版:是否可以查询特定日期对应的所有timeuuid列?

更多细节:

我有一个表定义如下:

CREATE TABLE timetest(
  key uuid,
  activation_time timeuuid,
  value text,
  PRIMARY KEY(key,activation_time)
);

我已经用一行填充了它,如下(f0532ef0-2a15-11e3-b292-51843b245f21 是与日期 2013-09-30 22:19:06+0100 对应的 timeuuid):

insert into timetest (key, activation_time, value) VALUES (7daecb80-29b0-11e3-92ec-e291eb9d325e, f0532ef0-2a15-11e3-b292-51843b245f21, 'some value'); 

我可以按如下方式查询该行:

select activation_time,dateof(activation_time) from timetest where key=7daecb80-29b0-11e3-92ec-e291eb9d325e

结果如下(使用 cqlsh)

 activation_time                      | dateof(activation_time)
--------------------------------------+--------------------------
 f0532ef0-2a15-11e3-b292-51843b245f21 | 2013-09-30 22:19:06+0100

现在假设我的表中有很多数据,我想检索activation_time 对应于特定日期的所有行,比如2013-09-30 22:19:06+0100

我本来希望能够查询 minTimeuuid('2013-09-30 22:19:06+0100')maxTimeuuid('2013-09-30 22:19:06+0100') 之间所有 timeuuid 的范围,但这似乎不可能(以下查询返回零行):

select * from timetest where key=7daecb80-29b0-11e3-92ec-e291eb9d325e and activation_time>minTimeuuid('2013-09-30 22:19:06+0100') and activation_time<=maxTimeuuid('2013-09-30 22:19:06+0100'); 

看来我需要使用 hack 来增加查询中的第二个日期(增加一秒)来捕获行,即

select * from timetest where key=7daecb80-29b0-11e3-92ec-e291eb9d325e and activation_time>minTimeuuid('2013-09-30 22:19:06+0100') and activation_time<=maxTimeuuid('2013-09-30 22:19:07+0100');

这感觉不对。我错过了什么吗?有没有更清洁的方法来做到这一点?

CQL 文档讨论了 timeuuid functions,但它对带有 timeuuids 的 gte/lte 表达式非常短:

min/maxTimeuuid 示例选择 timeuuid 列 t 严格晚于 2013-01-01 00:05+0000 但严格早于 2013-02-02 10:00+0000 的所有行。 t >= maxTimeuuid('2013-01-01 00:05+0000') 不会选择恰好在 2013-01-01 00:05+0000 生成的 timeuuid,本质上等同于 t > maxTimeuuid('2013-01 -01 00:05+0000')。

附言以下查询也返回零行:

select * from timetest where key=7daecb80-29b0-11e3-92ec-e291eb9d325e and activation_time<=maxTimeuuid('2013-09-30 22:19:06+0100'); 

以下查询返回行:

select * from timetest where key=7daecb80-29b0-11e3-92ec-e291eb9d325e and activation_time>minTimeuuid('2013-09-30 22:19:06+0100');

【问题讨论】:

    标签: cassandra cql


    【解决方案1】:

    我确定问题在于 cqlsh 不显示您的时间戳的毫秒数 所以真正的时间戳类似于'2013-09-30 22:19:06.123+0100' 当您在缺少毫秒时调用 maxTimeuuid('2013-09-30 22:19:06+0100') 时,假定为零,因此与调用 maxTimeuuid('2013-09-30 22:19:06.000+0100) 相同')

    而 22:19:06.123 > 22:19:06.000 会导致记录被过滤掉。

    【讨论】:

    • 优秀!非常感谢!!!就是这样。不幸的是,您不能将带有毫秒的日期传递给 minTimeuuid 或 maxTimeuuid ......但这是另一个问题......如果我计算 min/max timeuuids 并将它们传递给查询,它会起作用,例如select * from timetest where key=7daecb80-29b0-11e3-92ec-e291eb9d325e and activation_time&gt;f0532ef0-2a15-11e3-8080-808080808080 and activation_time&lt;f05355ff-2a15-11e3-7f7f-7f7f7f7f7f7f;
    • 仅供参考:我在 apache jira 上记录了问题 CASSANDRA-6395 以启用毫秒精度查询。谢谢@dimas,如果没有你的帮助,永远不会发现这个问题:-)
    • 如果我是你,我不会在 Java 中进行自己的 timeuuid 计算,而是会操纵查询的结束时间(通过将其推进到下一秒并将毫秒归零),然后按时间过滤
    • 同意。我一直在编写基于 ISO8601 格式字符串(不是 UUID)的测试,它们与存储在数据库中的内容不太匹配(如您建议的那样以毫秒为单位)。我犯的根本错误是我的测试预期的是第二粒度日期。即使知道这一点(感谢您的回答),我也无法进行亚秒级查询 - 谢天谢地,感谢CASSANDRA-6395,这现在是可能的。一切都很好:-)
    【解决方案2】:

    与答案没有直接关系,但作为@dimas 答案的附加插件。
    cqlsh(版本 5.0.1)现在似乎显示毫秒

     system.dateof(id)  
    ---------------------------------
     2016-06-03 02:42:09.990000+0000
     2016-05-28 17:07:30.244000+0000
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多