Простейший пример запроса по диапазону дат в Кассандре 1.x - PullRequest
3 голосов
/ 26 декабря 2011

Я хочу сохранить идентификатор и дату, и я хочу получить все записи от даты A до даты B, что именно мне нужно для выполнения select from my_column_family where date >= dateA and date < dateB;?

Ответы [ 2 ]

1 голос
/ 28 декабря 2011

Есть несколько способов решить эту проблему. Самым простым, вероятно, является решение с вторичным индексом с ограничением равенства, упомянутым в вашем собственном ответе. Я использовал этот метод, добавив дополнительный столбец с именем 'valid', установив значение в 1. Тогда запросы могут стать , где valid = 1 и date> nnnn

Для других решений требуются дополнительные семейства столбцов и дополнительные запросы.

При загрузке данных создайте и добавьте в семейство столбцов, которое содержит временные метки в качестве ключей, и в каждой записи будут перечислены все идентификаторы пользователей в качестве имен столбцов.

Если упорядочена стратегия разделения, то один RangeSliceQuery может указать диапазон дат в качестве диапазона ключей и получить все столбцы для каждого ключа. Затем переберите ключи результата, используя значения столбцов для каждого идентификатора пользователя, и, если необходимо, запросите исходное семейство столбцов для данных, связанных с каждым идентификатором. Кассандра всегда сохраняет отсортированные имена столбцов и может быть перевернута при чтении.

Но, как задокументировано , упорядоченный разделитель не идеален, что приводит к горячим точкам и затруднению балансировки нагрузки узлов.

Без упорядоченного секционера, сохраняющего семейство столбцов временных меток, вам придется создавать другое семейство столбцов при загрузке данных, где вы можете хранить все временные метки в виде столбцов под одним или несколькими известными ключами (например, «создан» или «обновлен»). «). Первый запрос будет SliceQuery для известного ключа, а затем имена столбцов (как метки времени) будут предоставлять ключи для MultigetSliceQuery к семейству столбцов меток времени.

Я использовал варианты этого, обычно добавляя составные ключи или столбцы для дополнительной гибкости.

1 голос
/ 27 декабря 2011

ребята из #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;, и он будет фильтроваться правильно.

...