How to use cql queries to get different datatypes out of cassandra with java client hector

时光毁灭记忆、已成空白 提交于 2020-01-12 07:11:27

问题


I'm new to cassandra and hector so i'm trying to execute cql queries but the problem is that not all columns are of type string so how dow I execute the query "select * from users"?

My column family looks like this:

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}
];

I use the following code to execute the query:

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("");
        }
    }

But because of the 'birth_year' column with validation class Long I can't get the value. I get the following result assuming that there is only one record:

KEY:Carl birth_year: 'strange chars?' full_name:Carl Smith gender:M eduction:electrician state:LA

If I change my query to this:

CqlQuery<String, String, Long> cqlQuery =  new CqlQuery<String, String, Long>
TutorialBase.tutorialKeyspace, stringSerializer, stringSerializer, longSerializer);

    cqlQuery.setQuery("select birth_year from users");

Than it works.

So how can I do this with only one query and what if I have more datatypes like booleans and floats in the rows of a column family?


回答1:


You specify the value type as String in the CqlRows, so every value is expected to be a string. Because you want to mix Value types, you should keep the column metadata, but also specify the default validation class as BytesType in the schema and then use ByteBuffer as the type in CqlRows:

QueryResult<CqlRows<String, String, ByteBuffer>> result = cqlQuery.execute();

Then, when processing the values, you will have to convert to the appropriate type, and instead of iterating through the columns, you will probably get the specific column by name:

ColumnSlice<String, ByteBuffer> slice = row.getColumnSlice();
HColumn<String,ByteBuffer> col = slice.getColumnByName("birth_year");
System.out.println(" birth_year: " + col.getValue().getLong());

Of course, Strings have to be handled differently, using java.nio.charset.Charset:

Charset.defaultCharset().decode(col.getValue()).toString()

You can determine types from the Column meta-data, but I've only done this via the Thrift API (see ColumnDef), so not sure how to do it via Hector API. But HColumn does provide a getValueSerializer() method, so that could be a start.



来源:https://stackoverflow.com/questions/7732651/how-to-use-cql-queries-to-get-different-datatypes-out-of-cassandra-with-java-cli

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!