2016-03-01 65 views
1

我有以下卡桑德拉表如何为WHERE条件

cqlsh:mydb> describe table events; 

CREATE TABLE mydb.events (
    id uuid PRIMARY KEY, 
    country text, 
    insert_timestamp timestamp 
) WITH bloom_filter_fp_chance = 0.01 
    AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}' 
    AND comment = '' 
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'} 
    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'} 
    AND dclocal_read_repair_chance = 0.1 
    AND default_time_to_live = 0 
    AND gc_grace_seconds = 864000 
    AND max_index_interval = 2048 
    AND memtable_flush_period_in_ms = 0 
    AND min_index_interval = 128 
    AND read_repair_chance = 0.0 
    AND speculative_retry = '99.0PERCENTILE'; 
CREATE INDEX country_index ON mydb.events (country); 
CREATE INDEX insert_timestamp_index ON mydb.events (insert_timestamp); 

正如你可以看到Cassandra的timestamp列进行查询,指数已经在insert_timestamp列上创建。

我已通过https://stackoverflow.com/a/18698386/3238864

走后,我虽然下面是正确的查询

cqlsh:mydb> select * from events where insert_timestamp >= '2016-03-01 08:27:22+0000'; 
InvalidRequest: code=2200 [Invalid query] message="No secondary indexes on the restricted columns support the provided operators: 'insert_timestamp >= <value>'" 

cqlsh:mydb> select * from events where insert_timestamp >= '2016-03-01 08:27:22+0000' ALLOW FILTERING; 
InvalidRequest: code=2200 [Invalid query] message="No secondary indexes on the restricted columns support the provided operators: 'insert_timestamp >= <value>'" 

但是,随着countryWHERE条件不工作查询。

cqlsh:mydb> select * from events where country = 'my'; 

id         | country | insert_timestamp 
--------------------------------------+---------+-------------------------- 
53167d6a-e125-46ff-bacf-f5b267de0258 |  my | 2016-03-01 08:27:22+0000 

任何想法为什么查询与时间戳条件不起作用?我的查询语法有什么问题吗?

+0

[Cassandra CQL范围查询可能被重复,尽管等于运算符和二级索引](http://stackoverflow.com/questions/24894393/cassandra-cql-range-query-rejected-despite-equality-operator-and- secondary index) –

回答

1

对二级索引的直接查询仅支持=,CONTAINS或 CONTAINS KEY限制。

次要索引的查询可以限制返回的结果 使用=,>,> =,< =和<,CONTAINS和CONTAINS KEY限制 上使用滤波非索引列。

因此,只要您将其添加ALLOW FILTERING即可。

select * from events where insert_timestamp >= '2016-03-01 08:27:22+0000' ALLOW FILTERING; 

您在问题中提到的链接具有timestamp列作为集群键。因此它在那里工作。

作为每注释RangeQuery on secondary index is not alllowed upto 2.2.x version

供参考: 当卡桑德拉必须执行二次索引查询时,它会接触的所有节点,以检查位于每个节点上的二级索引的一部分。 因此,它被认为是卡桑德拉的反模式,像时间戳那样拥有高基数列的索引。 您应该考虑更改您的数据模型以适合您的查询。

+0

我执行'ALLOW FILTERING'版本作为你的。但我仍然遇到同样的错误。 –

+0

我编辑了我的答案。请看看 –

5

任何想法为什么查询与时间戳条件不起作用?我的查询语法有什么问题吗?

原生Cassandra二级索引被限制为=谓词。为了使不平等谓词需要添加允许过滤的,但将执行全集群扫描 :-(

如果你能负担得起等待几个星期,卡桑德拉3.4将与新SASI发布二级索引对于范围查询更有效:https://github.com/apache/cassandra/blob/trunk/doc/SASI.md

+0

这个答案非常有用,我的朋友谁不能upvote是要我upvote来表示感谢:) –

0

cassandra中的索引与关系数据库中的索引完全不同,其中一个区别在于cassandra索引中的范围查询是完全不允许的。通常,范围查询仅适用于集群密钥(如果使用ByteOrderPartitioner,它也可以与分区密钥一起使用,但并不常见),这意味着您必须仔细设计您的columnfamilies以适合您的潜在查询模式。已经有many discussions in StackOverflow for the same topic

要了解什么时候使用Cassandra的指数(它是专为非常特殊的情况下)和它的局限性,this是一个不错的职位,

0

使用cequel ORM

now = DateTime.now 
    today = DateTime.new(now.year, now.month, now.day, 0, 0, 0, now.zone) 
    tommorrow = today + (60 * 60 * 24); 
    MyObject.allow_filtering!.where("done_date" => today..tommorrow).select("*") 

已经为我工作。