我第一次在网络应用中使用Cassandra而且我遇到了查询问题。 这是我的标签:
CREATE TABLE vote (
doodle_id uuid,
user_id uuid,
schedule_id uuid,
vote int,
PRIMARY KEY ((doodle_id), user_id, schedule_id)
);
在每个请求中,我都指示我的分区键doodle_id。 例如,我可以毫无问题地制作:
select * from vote where doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 and user_id = 97a7378a-e1bb-4586-ada1-177016405142;
但是在我提出的最后一个请求中:
select * from vote where doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 and schedule_id = c37df0ad-f61d-463e-bdcc-a97586bea633;
我收到以下错误:
Bad Request: PRIMARY KEY column "schedule_id" cannot be restricted (preceding column "user_id" is either not restricted or by a non-EQ relation)
我是Cassandra的新手,但如果我错了,请更正我,在复合主键中,第一部分是PARTITION KEY,必须允许Cassandra知道在哪里查找数据。 然后其他部分是CLUSTERING KEY来对数据进行排序。
但我仍然不知道为什么我的第一个请求正在运行而不是第二个请求?
如果有人能提供帮助,那将是一件非常愉快的事。
答案 0 :(得分:13)
在Cassandra中,您应该设计适合您查询的数据模型。因此,支持第二个查询的正确方法(doodle_id
和schedule_id
进行查询,但不必使用user_id
),是创建一个新表来处理该特定查询。这个表几乎是一样的,除了PRIMARY KEY会略有不同:
CREATE TABLE votebydoodleandschedule (
doodle_id uuid,
user_id uuid,
schedule_id uuid,
vote int,
PRIMARY KEY ((doodle_id), schedule_id, user_id)
);
现在这个查询将起作用:
SELECT * FROM votebydoodleandschedule
WHERE doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7
AND schedule_id = c37df0ad-f61d-463e-bdcc-a97586bea633;
这使您无需指定ALLOW FILTERING
。依赖ALLOW FILTERING
永远不是一个好主意,当然不是你应该在生产集群中做的事情。
答案 1 :(得分:3)
群集密钥还用于查找给定分区中的列。使用您的模型,您将能够通过以下方式进行查询:
ALLOW FILTERING
ALLOW FILTERING
您可以将主键视为文件路径doodle_id#123 / user_id#456 / schedule_id#789,其中所有数据都存储在最深的文件夹中(即schedule_id#789)。当您查询时,您必须从开始搜索的位置指出子文件夹/子树。
您的第二个查询不起作用,因为列在分区中的组织方式。 Cassandra无法在分区中获得连续的 slice 列,因为它们是交错的。
您应该反转主键顺序(doodle_id,schedule_id,user_id)才能运行查询。