在Cassandra表的任何列中使用IN

时间:2018-07-03 22:25:48

标签: cassandra cassandra-3.0

我希望能够在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

1 个答案:

答案 0 :(得分:1)

cassandra的主键有很多混乱之处。 为了回答您的问题,我认为您需要了解cassandra主键在内部如何工作。

在创建具有多个字段的主键时(如您的情况):

CREATE TABLE test (a TEXT, b TEXT, c TEXT, PRIMARY KEY (a, b, c));
  • “ a”将是 分区键 ,您可以将其想象成一个散列,它将选择要在其上分发数据的分区。
  • b和c将是 集群键 ,这些键将类似于数据的排序列表,并且c将嵌套在每个b值中,这意味着您必须提供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;

以此类推,我想你明白了。 但实际上,要尽力而为,以最大程度地减少允许过滤的使用。并记住直接对分区键进行查询将是最快的。