我是新来的Cassandra。我有一个问题时,使用在Cassandra查询。
如果表中没有SET类型的列,则它有效。
CREATE TABLE test (
test_date bigint,
test_id bigint,
caption text,
PRIMARY KEY(test_date,test_id)
);
select * from test where test_date = 2022015 and test_id IN (1,2);
但是,如果我在上表中添加SET类型的列(例如,标记set)并重新运行选择查询,则会出现错误。
CREATE TABLE test1 (
test_date bigint,
test_id bigint,
tags set<text>,
caption text,
PRIMARY KEY(test_date,test_id)
);
select * from test1 where test_date = 2022015 and test_id IN (1,2);
code=2200 [无效查询] message=“无法通过IN关系限制列“test_id”,因为查询选择了一个集合”
3条答案
按热度按时间ui7jx7zq1#
我不知道为什么这个限制应该特别适用于集合,但是在您的情况下,您可以通过将test_id作为分区键的一部分来解决这个问题:
PRIMARY KEY((test_date,test_id))
这将允许您执行IN查询,只要您指定了组合键的第一部分(test_date)。
dgtucam12#
我认为您看到的这个错误是由于Cassandra的底层存储模型造成的。当我在CQLSH中查询您的
test1
表时(使用我自己的测试数据),我看到的是:这个视图给出了一个关于数据实际存储方式的误导性解释,这是我在cassandra-cli中查询同一个表时看到的情况:
这意味着集合(集)值被存储为附加列键。使用
IN
关系的限制是它必须在主键的最后一个键(分区或聚类)上操作。所以我猜这是基于Cassandra如何"在引擎盖下"存储集合数据的限制。这只是一个警告,但是不推荐将
IN
用于生产级查询。有些人甚至把它放在Cassandra反模式列表中。我对这个问题的回答(Cassandra中的IN关系对查询不好吗?)解释了为什么IN
查询不是最优的。只是为了看看,我尝试了使用列表而不是集合的模式,看看这是否有什么不同。它仍然不起作用,但在cassandra-cli中,它似乎向键添加了一个额外的UUID标识符,并将实际值存储为列值。这与处理集合的方式不同...这一定是集合限制为唯一值的方式。
hfyxw5xn3#
如果无法更改基表上的PK,则可以使用具有test_id的实体化视图作为分区表达式的一部分来满足您的要求:
然后在查询中使用实体化视图而不是基表: