Как использовать 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(), так что это может быть началом.

Другие вопросы по тегам