聚类列非EQ关系

时间:2016-04-20 17:49:40

标签: cassandra datastax-java-driver

有一张桌子

CREATE TABLE room (
    uuidhotel text,
    startreservetime double,
    endreservetime double,
    uuid text,
    uuidguest text,
    uuidroom text,
    PRIMARY KEY (uuidhotel, startreservetime, endreservetime)

这样的查询有效:

select * from room WHERE uuidhotel = 'testUUIDHotel' and startreservetime > 1;

但是当我尝试使用时:

cqlsh:hotelier> select * from room WHERE uuidhotel = 'testUUIDHotel' and startreservetime > 1 and endreservetime < 3;

出错了。

InvalidRequest: code=2200 [Invalid query] message="Clustering column "endreservetime" cannot be restricted (preceding column "startreservetime" is restricted by a non-EQ relation)

如何使用3个参数执行查询?

任何替代方案?

2 个答案:

答案 0 :(得分:0)

不幸的是,如果你想在Cassandra的PRIMARY KEY组件上使用more / less-than运算符,那么必须用equals运算符限制所有前面的PRIMARY KEY组件。

那么如何查询日期范围?那么,您可以指定相同的PRIMARY KEY组件两次。目前,这对你没有帮助。但是通过一个小的建模更改(加上每行存储两次......一次开始,一次开始),它确实:

aploetz@cqlsh:stackoverflow> SELECT * FROM room WHERE uuidhotel = 'testUUIDHotel' 
  AND reservetime > 1 AND reservetime < 3;

 uuidhotel     | reservetime | startend | uuid                                 | uuidguest                            | uuidroom
---------------+-------------+----------+--------------------------------------+--------------------------------------+--------------------------------------
 testUUIDHotel |         2.1 |        S | 49c441cd-a6cd-4638-85b3-fdc3405779f4 | cd3ad747-42a3-4d31-b02a-8190dd8559d8 | daae89d5-abd3-4cac-b4cc-aec9d6b7fb1f
 testUUIDHotel |         2.2 |        E | 49c441cd-a6cd-4638-85b3-fdc3405779f4 | cd3ad747-42a3-4d31-b02a-8190dd8559d8 | daae89d5-abd3-4cac-b4cc-aec9d6b7fb1f

(2 rows)

基本上,如果您为每个开头和结尾存储一个条目,(并在密钥中使用startend表示唯一性),您将能够以更高/更低的方式进行有效查询。时间。只需确保您查询的是一个广泛的差距,而您不会在您关注的reservetime范围之间进行查询。

答案 1 :(得分:0)

编辑:显然元组比较不像我认为的那样工作...下面的答案不起作用,它比较整个元组而不是单个元素,即(1,2) < (3,1)返回真正。离开它,以防它激发更好的方法......

另一种方法,你可以query with non-EQ conditions on multiple clustering columns using tuples

但是,它需要您有一个非EQ运算符,即您的查询必须如下所示:

SELECT * FROM table WHERE (c1, c2) > (1, 3)

因此,您必须转换您的值,以便您可以使用单个运算符。你可以通过否定双方来做到这一点!

记住代数:

5 < 10

如果你否定双方,你必须切换操作员:

-5 > -10

所以使用negative_c2中的否定值创建一个新列c2并执行查询:

SELECT * FROM table WHERE (c1, negative_c2) > (1, -3)