Как использовать cql-запросы для получения разных типов данных из cassandra с помощью Java-клиента Hector
Я новичок в cassandra и hector, поэтому я пытаюсь выполнить запросы cql, но проблема в том, что не все столбцы имеют строковый тип, так как мне выполнить запрос "select * from users"?
Моя семья столбцов выглядит так:
UPDATE COLUMN FAMILY users
WITH comparator = UTF8Type
AND key_validation_class=UTF8Type
AND column_metadata = [
{column_name: full_name, validation_class: UTF8Type}
{column_name: email, validation_class: UTF8Type}
{column_name: state, validation_class: UTF8Type, index_type: KEYS}
{column_name: gender, validation_class: UTF8Type}
{column_name: birth_year, validation_class: LongType, index_type: KEYS}
{column_name: education, validation_class: UTF8Type}
];
Я использую следующий код для выполнения запроса:
CqlQuery<String, String, String> cqlQuery = new CqlQuery<String, String, String>(Keyspace,stringSerializer,stringSerializer,stringSerializer);
cqlQuery.setQuery("select * from users");
QueryResult<CqlRows<String, String, String>> result = cqlQuery.execute();
if (result != null && result.get() != null) {
List<Row<String, String, String>> list = result.get().getList();
for (Row row : list) {
System.out.println(".");
List columns = row.getColumnSlice().getColumns();
for (Iterator iterator = columns.iterator(); iterator.hasNext();) {
HColumn column = (HColumn) iterator.next();
System.out.print(column.getName() + ":" + column.getValue()
+ "\t");
}
System.out.println("");
}
}
Но из-за столбца birth_year с классом проверки Long я не могу получить значение. Я получаю следующий результат, предполагая, что есть только одна запись:
KEY:Carl birth_year: 'strange chars?' full_name:Carl Smith gender:M eduction:electrician state:LA
Если я изменю свой запрос на это:
CqlQuery<String, String, Long> cqlQuery = new CqlQuery<String, String, Long>
TutorialBase.tutorialKeyspace, stringSerializer, stringSerializer, longSerializer);
cqlQuery.setQuery("select birth_year from users");
Чем это работает.
Итак, как я могу сделать это только с одним запросом и что, если у меня есть больше типов данных, таких как логические значения и числа с плавающей запятой в строках семейства столбцов?
1 ответ
Вы указываете тип значения как String в CqlRows, поэтому каждое значение должно быть строкой. Поскольку вы хотите смешивать типы значений, вы должны сохранить метаданные столбца, а также указать класс проверки по умолчанию как BytesType в схеме, а затем использовать ByteBuffer в качестве типа в CqlRows:
QueryResult<CqlRows<String, String, ByteBuffer>> result = cqlQuery.execute();
Затем при обработке значений вам придется преобразовать в соответствующий тип, и вместо того, чтобы перебирать столбцы, вы, вероятно, получите конкретный столбец по имени:
ColumnSlice<String, ByteBuffer> slice = row.getColumnSlice();
HColumn<String,ByteBuffer> col = slice.getColumnByName("birth_year");
System.out.println(" birth_year: " + col.getValue().getLong());
Конечно, строки должны обрабатываться по-разному, используя java.nio.charset.Charset:
Charset.defaultCharset().decode(col.getValue()).toString()
Вы можете определять типы из метаданных Column, но я делал это только через Thrift API (см. ColumnDef), поэтому не уверен, как это сделать через Hector API. Но HColumn предоставляет метод getValueSerializer(), так что это может быть началом.