2016-04-20 1 views
1

есть таблицакластеризация колонка не-EQ отношение

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) 

Как выполнить запрос с тремя параметрами?

Любые альтернативы?

ответ

1

К сожалению, если вы хотите использовать оператор большего или меньшего размера для компонента PRIMARY KEY в Cassandra, все предыдущие компоненты PRIMARY KEY должны быть ограничены оператором equals.

Итак, как вы можете запросить диапазон дат? Ну, вы можете указать один и тот же компонент PRIMARY KEY дважды. В настоящее время это вам не поможет. Но с небольшим изменением моделирования (в сочетании с хранением каждой строки в два раза ... один раз для начала и снова в конце) он делает:

[email protected]: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 s, о котором вы беспокоитесь.

+0

Если у вас есть строка с временем начала 2 и временем окончания 10 , он также будет выбран. – spiffman

+0

Да, это правильно. Суть в том, что ваши модели должны быть построены вокруг ваших запросов, и ваши запросы должны быть построены вокруг ваших бизнес-требований.Поэтому, возможно, это необходимо будет скорректировать на основе этого. – Aaron

0

EDIT: Видимо кортеж сравнения не работают так, как я думал, что они ... ответ ниже не работает, он сравнивает весь кортеж, а не отдельные элементы, т.е. (1,2) < (3,1) возвращает истину. Оставляя его на случай, если он вдохновит на лучший метод ...

Другой подход, вы можете query with non-EQ conditions on multiple clustering columns using tuples.

Однако, это потребует от вас есть один оператор без эквалайзера, то есть ваш запрос должен выглядеть следующим образом:

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

Таким образом, вы должны преобразовать ваши ценности таким образом, что вы можете использовать один оператор , Вы можете сделать это, отрицая обе стороны!

Вспомните из алгебры:

5 < 10 

Если вы отрицать обе стороны, вы должны переключить оператор:

-5 > -10 

Так создать новый столбец negative_c2 с отрицаниями значений из c2 и творите запрос:

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