总结一下,我想创建一个SMACK体系结构(Spark,Mesos,Akka,Cassandra和Kafka)。我想创建一个入口点,可以在数据库中返回最后添加的50个元素。这是我的数据库:
create table fireman
(
uuid uuid primary key,
date text,
heartrate int,
id text,
location text,
ratecommunication int,
temperature int,
time timestamp
);
我试图查询:
SELECT * FROM scala_fireman.fireman WHERE temperature > 0 ORDER BY date LIMIT 5 ALLOW FILTERING ;
但是我得到了这个错误:
ORDER BY is only supported when the partition key is restricted by an EQ or an IN.
所以我的问题是如何选择SELECT以获得我添加的最后n个元素?
我看到可以通过执行以下操作来对表格进行排序:
) WITH CLUSTERING ORDER BY (time DESC);
但是要做到这一点,我需要将时间更改为主键,但是同时添加了一些数据,因此我无法将其设置为主键。
答案 0 :(得分:3)
由于Cassandra需要基于查询的建模方法,因此我们需要专门构建一个表来处理此查询:
SELECT * FROM scala_fireman.fireman
WHERE temperature > 0 ORDER BY date LIMIT 5 ALLOW FILTERING;
您是否曾经通过uuid
进行查询?如果是这样,那么我们可以建立一个新表。如果没有,您将需要更改您的主键才能起作用。在ID列上构建单个PRIMARY KEY会严重限制您的查询灵活性(如您所发现的那样)。
这是一个尽可能多的POC,目前我已派出100万消防员
这将是您的第一个障碍。 Cassandra每个分区只能支持20亿个单元,而在此之前它会变得很慢。因此,我们将要通过“时间分段”来限制每个分区的消防员事件数量。例如,我将使用month_bucket
,但是您应该确定它是否真的适合您的业务需求。
接下来,您想要ORDER BY
日期,因此我们将其用作聚类键。实际上,由于date
是一个文本字段,我们将使用time
,因为我确定您不希望返回的结果以ASCII字母顺序排列。对ORDER BY
子句的快速了解是完全多余的。您可以仅按集群键的预定顺序强制实施。永远不需要在查询中。
注意:出现错误的原因是,排序顺序只能在数据分区的内执行。不能在结果集上强制使用它。
此外,我看到您正在对temperature
进行开放式范围查询。通常,这是个坏主意(也是您在原始查询中需要ALLOW FILTERING
的原因)。但是在分区中,应该不会太糟。只要该分区不是太大。我们也将以此为基础。
当然,有可能多个消防员可能在同一日期,同一温度下参与同一事件,因此我们将在末尾添加uuid
以强制执行唯一性。您的新主键应如下所示:
PRIMARY KEY ((month_bucket),time,temperature,uuid))
因此,如果尝试使用此表定义:
create table fireman_events_by_date_and_temp (
uuid uuid,
month_bucket int,
date text,
heartrate int,
id text,
location text,
ratecommunication int,
temperature int,
time timestamp,
PRIMARY KEY ((month_bucket),time,temperature,uuid))
WITH CLUSTERING ORDER BY (time DESC, temperature ASC, uuid ASC);
现在,如果我加载一些数据并运行您的查询:
> SELECT time,temperature,heartrate,location
FROM fireman_events_by_date_and_temp
WHERE month_bucket=201904
AND temperature > 0
LIMIT 5
ALLOW FILTERING;
time | temperature | heartrate | location
---------------------------------+-------------+-----------+----------
2019-04-30 13:40:03.253000+0000 | 644 | 144 | SF
2019-04-30 13:39:51.944000+0000 | 644 | 144 | SF
2019-04-30 13:39:39.859000+0000 | 644 | 144 | SF
2019-04-30 13:39:30.331000+0000 | 644 | 144 | SF
2019-04-30 13:39:15.945000+0000 | 644 | 144 | NY
(5 rows)
通常,我不建议使用ALLOW FILTERING
。但是,只要您要查询分区键(month_bucket
),所有数据仍应由同一节点提供。
此外,我在2015年用Cassandra撰写了关于结果集排序的文章,并在其中演示了这些建模技术的用法。四年后,它仍然非常重要(尤其是对于像这样的问题):
阅读,看看是否有帮助。