ребята из #cassandra (IRC) помогли мне найти способ, есть много тонких деталей, поэтому я хотел бы документировать это здесь.
сначала вам нужно объявить семейство столбцов, подобное этому (примеры из cassandra-cli):
create column family users with comparator=UTF8Type and key_validation_class=UTF8Type and column_metadata=[
{column_name: id, validation_class: LongType}
{column_name: name, validation_class: UTF8Type, index_type: KEYS}
{column_name: age, validation_class: LongType}
];
несколько важных вещей об этой декларации:
- есть компаратор и key_validation_class, чтобы можно было использовать строки в качестве имен ключей
- первый объявленный столбец является специальным, это «ключ строки», который используется для адресации каждой строки и, следовательно, не может содержать повторяющиеся значения (INSERT действительно является UPSERT, поэтому при наличии дубликатов новые значения перезаписывают старые)
- второй столбец объявляет «вторичный индекс» в своих значениях (подробнее об этом ниже)
- даты хранятся в виде длинных типов данных, интерпретация до клиента
Теперь давайте добавим несколько значений:
set users[1][name] = john;
set users[1][age] = 19;
set users[2][name] = jane;
set users[2][age] = 21;
set users[3][name] = john;
set users[3][age] = 32;
в соответствии с этим: http://pkghosh.wordpress.com/2011/03/02/cassandra-secondary-index-patterns/ Cassandra не поддерживает операторы <
, она вручную исключает строки, которые не совпадают, но делает это после ПОСЛЕ набора результатов и также отказывается делайте это, пока не произойдет фактическая фильтрация.
это означает, что запрос типа get users where age > 20;
вернет null
, но если мы добавим предикат, включающий =
, он будет работать волшебным образом.
здесь важен вторичный индекс, без него вы не сможете использовать =
, поэтому в этом примере я могу сделать get users where name = jane;
, но не могу запросить get users where age = 21;
забавно то, что после использования =
работает <
, поэтому наличие вторичного индекса позволяет запрашивать get users where name = john and age > 20;
, и он будет фильтроваться правильно.