我希望能够在Cassandra中以任何顺序在任何列中使用IN
所以我有下一张桌子:
CREATE TABLE test (a TEXT, b TEXT, c TEXT, PRIMARY KEY (a, b, c));
和此数据:
INSERT INTO test (a, b, c) VALUES ('a1', 'b1', 'c1');
INSERT INTO test (a, b, c) VALUES ('a2', 'b2', 'c2');
此查询有效:
SELECT * FROM test WHERE c IN ('c1', 'c2') AND b IN ('b1') ALLOW FILTERING;
但是,如果您删除b IN
,则会出现此错误:
SELECT * FROM test WHERE c IN ('c1', 'c2') ALLOW FILTERING;
InvalidRequest: Error from server: code=2200 [Invalid query] message="IN
restrictions are not supported on indexed columns"
好像我想在一列中使用IN
一样,我应该在前几列中使用IN
吗?
有办法避免这种情况吗?
修改架构是valid
,但我需要使用Cassandra并允许对任何列进行过滤(如果不需要过滤某个列,则该列将没有IN
子句)。
感谢阅读。
P.S:我知道您不应该使用ALLOW FILTERING
,请假设没有其他方法。
编辑:好像他们已经解决了这个问题?:https://issues.apache.org/jira/browse/CASSANDRA-14344
答案 0 :(得分:1)
cassandra的主键有很多混乱之处。 为了回答您的问题,我认为您需要了解cassandra主键在内部如何工作。
在创建具有多个字段的主键时(如您的情况):
CREATE TABLE test (a TEXT, b TEXT, c TEXT, PRIMARY KEY (a, b, c));
cassandra文档指出,您只能在分区键的最后一列和集群键的最后一列使用In子句,但要注意,您必须提供所有其他集群键。
所以基本上没有办法在一张桌子上做到这一点。
您应该考虑查询灵活性与数据重复之间的权衡。 一种解决方案是像这样在2个表中对数据进行非规范化:
CREATE TABLE test1 (a TEXT, b TEXT, c TEXT, PRIMARY KEY (a, b));
CREATE TABLE test2 (a TEXT, b TEXT, c TEXT, PRIMARY KEY (c, a, b));
这样做,您将能够根据用例查询每个表。 以下查询将起作用:
SELECT * FROM test2 WHERE c IN ('c1', 'c2');
SELECT * FROM test1 WHERE a IN ('a1', 'a2');
SELECT * FROM test1 WHERE b IN ('b1', 'b2') ALLOW FILTERING;
以此类推,我想你明白了。 但实际上,要尽力而为,以最大程度地减少允许过滤的使用。并记住直接对分区键进行查询将是最快的。