Cassandra:使用where子句查询包含更大或更小的(<和>)

Wol*_*er 7 cql where-clause cassandra

我正在使用Cassandra 1.1.2我正在尝试将RDBMS应用程序转换为Cassandra.在我的RDBMS应用程序中,我有以下表名为table1:

| Col1 | Col2 | Col3 | Col4 |
Run Code Online (Sandbox Code Playgroud)
  1. Col1:String(主键)
  2. Col2:String(主键)
  3. Col3:Bigint(索引)
  4. Col4:Bigint

该表计有超过2亿条记录.最常用的查询类似于:

Select * from table where col3 < 100 and col3 > 50;
Run Code Online (Sandbox Code Playgroud)

在Cassandra中,我使用以下语句来创建表:

create table table1 (primary_key varchar, col1 varchar, 
col2 varchar, col3 bigint, col4 bigint, primary key (primary_key));

create index on table1(col3);
Run Code Online (Sandbox Code Playgroud)

我将主键更改为一个额外的列(我计算了我的应用程序中的键).导入几条记录后,我尝试执行以下cql:

select * from table1 where col3 < 100 and col3 > 50;
Run Code Online (Sandbox Code Playgroud)

结果是:

Bad Request: No indexed columns present in by-columns clause with Equal operator
Run Code Online (Sandbox Code Playgroud)

查询从table1中选择col1,col2,col3,col4,其中col3 = 67有效

谷歌表示无法执行这类查询.是对的吗?有什么建议如何创建这样的查询?

the*_*aul 7

Cassandra索引实际上不支持顺序访问; 请参阅http://www.datastax.com/docs/1.1/ddl/indexes,以便快速解释它们的用途.但不要绝望; 使用Cassandra(以及许多其他NoSQL系统)的更经典的方法是非规范化,非规范化,非规范化.

可能是你的情况使用经典斗范围模式,它可以让你使用推荐RandomPartitioner,并保持你行你周围的丛式井分布,同时还允许你的价值观顺序访问一个好主意.在这种情况下的想法是,您将第二个动态columnfamily映射(bucketed和ordered)col3值返回到相关primary_key值.例如,如果您的col3值范围从0到10 ^ 9并且分布相当均匀,您可能希望将它们放在1000个范围内,每个范围为10 ^ 6(最佳粒度级别取决于您需要的查询类型,您拥有的数据类型,查询往返时间等).cql3的示例模式:

CREATE TABLE indexotron (
    rangestart int,
    col3val int,
    table1key varchar,
    PRIMARY KEY (rangestart, col3val, table1key)
);
Run Code Online (Sandbox Code Playgroud)

当插入table1,你应该插入相应的行indexotron,用rangestart = int(col3val / 1000000).然后,当您需要table1使用col3> X 枚举所有行时,您需要查询最多1000个桶indexotron,但是其中的所有内容都col3val将被排序.用于查找以下所有table1.primary_key值的示例查询table1.col3 < 4021:

SELECT * FROM indexotron WHERE rangestart = 0 ORDER BY col3val;
SELECT * FROM indexotron WHERE rangestart = 1000 ORDER BY col3val;
SELECT * FROM indexotron WHERE rangestart = 2000 ORDER BY col3val;
SELECT * FROM indexotron WHERE rangestart = 3000 ORDER BY col3val;
SELECT * FROM indexotron WHERE rangestart = 4000 AND col3val < 4021 ORDER BY col3val;
Run Code Online (Sandbox Code Playgroud)