如何使用cql查询从java客户端hector获取cassandra中的不同数据类型

Rub*_*ski 9 cql cassandra 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}
];
Run Code Online (Sandbox Code Playgroud)

我使用以下代码来执行查询:

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("");
        }
    }
Run Code Online (Sandbox Code Playgroud)

但由于带有验证类Long的'birth_year'列,我无法获得该值.假设只有一条记录,我得到以下结果:

KEY:Carl birth_year: 'strange chars?' full_name:Carl Smith gender:M eduction:electrician state:LA
Run Code Online (Sandbox Code Playgroud)

如果我将查询更改为:

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

    cqlQuery.setQuery("select birth_year from users");
Run Code Online (Sandbox Code Playgroud)

比它的工作.

那么我怎么能只用一个查询来做这个呢?如果我在列系列的行中有更多数据类型如布尔值和浮点数呢?

lib*_*ack 11

您在CqlRows中将值类型指定为String,因此每个值都应该是一个字符串.因为要混合使用Value类型,所以应该保留列元数据,还要在模式中将默认验证类指定为BytesType,然后使用ByteBuffer作为CqlRows中的类型:

QueryResult<CqlRows<String, String, ByteBuffer>> result = cqlQuery.execute();
Run Code Online (Sandbox Code Playgroud)

然后,在处理值时,您必须转换为适当的类型,而不是遍历列,您可能会按名称获取特定列:

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

当然,使用java.nio.charset.Charset必须以不同的方式处理字符串:

Charset.defaultCharset().decode(col.getValue()).toString()
Run Code Online (Sandbox Code Playgroud)

您可以从Column元数据中确定类型,但我只通过Thrift API(参见ColumnDef)完成此操作,因此不确定如何通过Hector API执行此操作.但是HColumn确实提供了一个getValueSerializer()方法,所以这可能是一个开始.