Cassandra – 重叠数据范围

我在Cassandra中有以下’Tasks’表.

> Task_ID UUID – 分区键
> Starts_On TIMESTAMP – 聚类列
> Ends_On TIMESTAMP – 聚类列

我想运行一个CQL查询来获取给定日期范围的重叠任务.例如,如果我将两个时间戳(T1和T2)作为参数传递给查询,我想获得适用于该范围的所有任务(即重叠记录).

Cassandra最好的办法是什么?我不能在Starts_On和Ends_On上使用两个范围,因为要向Ends_On添加范围查询,我必须对Starts_On进行相等性检查.

最佳答案 这是另一个想法(有些不同寻常).您可以创建用户定义的函数来实现第二个范围过滤器(在Cassandra 2.2和更新版本中).

假设您像这样定义表(用ints而不是时间戳显示以保持示例简单):

CREATE TABLE tasks (
    p int, 
    task_id timeuuid, 
    start int, 
    end int, 
    end_range int static, 
    PRIMARY KEY(p, start));

现在我们创建一个用户定义的函数来根据结束时间检查返回的行,并返回匹配行的task_id,如下所示:

CREATE FUNCTION my_end_range(task_id timeuuid, end int, end_range int) 
    CALLED ON NULL INPUT RETURNS timeuuid LANGUAGE java AS 
    'if (end <= end_range) return task_id; else return null;';

现在我在第三个参数中使用了一个技巧.在明显的(主要?)疏忽中,似乎您无法将常量传递给用户定义的函数.因此,为了解决这个问题,我们将静态列(end_range)作为常量传递.

首先,我们必须设置我们想要的end_range:

UPDATE tasks SET end_range=15 where p=1;

让我们说我们有这些数据:

SELECT * FROM tasks;

 p | start | end_range | end | task_id
---+-------+-----------+-----+--------------------------------------
 1 |     1 |        15 |   5 | 2c6e9340-4a88-11e5-a180-433e07a8bafb
 1 |     2 |        15 |   7 | 3233a040-4a88-11e5-a180-433e07a8bafb
 1 |     4 |        15 |  22 | f98fd9b0-4a88-11e5-a180-433e07a8bafb
 1 |     8 |        15 |  15 | 37ec7840-4a88-11e5-a180-433e07a8bafb

现在让我们得到一个开始的> = 2并且结束< = 15的task_id:

SELECT start, end, my_end_range(task_id, end, end_range) FROM tasks 
    WHERE p=1 AND start >= 2;

 start | end | test.my_end_range(task_id, end, end_range)
-------+-----+--------------------------------------------
     2 |   7 |       3233a040-4a88-11e5-a180-433e07a8bafb
     4 |  22 |                                       null
     8 |  15 |       37ec7840-4a88-11e5-a180-433e07a8bafb

这样就可以为你提供匹配的task_id,你必须忽略空行(我还没有找到使用UDF删除行的方法).您会注意到start> = 2的过滤器在将其传递给UDF之前删除了一行.

无论如何,这显然不是一个完美的方法,但它可能是你可以使用的东西. 🙂

点赞