如何以编程方式向Cassandra 0.7添加索引

时间:2011-01-13 05:23:09

标签: java cassandra thrift cassandra-0.7

我尝试以编程方式在http://www.riptano.com/blog/whats-new-cassandra-07-secondary-indexes上运行演示,但结果与在CLI中运行它不同。似乎Cassandra只能在添加索引后对列进行索引。以前的所有数据都没有编入索引。

完整源代码如下: -

public static void main(String[] args) {
    try {
        try {
            transport.open();
        } catch (TTransportException ex) {
            Logger.getLogger(IndexLaterTest.class.getName()).log(Level.SEVERE, null, ex);
            System.exit(1);
        }
        KsDef ksDef = new KsDef();
        ksDef.name = KEYSPACE_NAME;
        ksDef.replication_factor = 1;
        ksDef.strategy_class = "org.apache.cassandra.locator.SimpleStrategy";
        CfDef cfDef = new CfDef(KEYSPACE_NAME, COLUMN_FAMILY_NAME);
        cfDef.comparator_type = "UTF8Type";
        ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap(FULL_NAME.getBytes()), "UTF8Type");

        cfDef.addToColumn_metadata(columnDef);
        ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap(BIRTH_DATE.getBytes()), "LongType");
        columnDef1.index_type = IndexType.KEYS;
        cfDef.addToColumn_metadata(columnDef1);
        ksDef.cf_defs = Arrays.asList(cfDef);
        try {
            client.system_add_keyspace(ksDef);

            client.set_keyspace(KEYSPACE_NAME);

            ColumnParent columnParent = new ColumnParent();
            columnParent.column_family = COLUMN_FAMILY_NAME;
            Column column = new Column(ByteBuffer.wrap(FULL_NAME.getBytes()), ByteBuffer.wrap("Brandon Sanderson".getBytes()), System.currentTimeMillis());
            client.insert(ByteBuffer.wrap("bsanderson".getBytes()), columnParent, column, ConsistencyLevel.ONE);
            column.name = ByteBuffer.wrap(BIRTH_DATE.getBytes());
            column.value = ByteBuffer.allocate(8).putLong(1975);
            client.insert(ByteBuffer.wrap("bsanderson".getBytes()), columnParent, column, ConsistencyLevel.ONE);

            column.name = ByteBuffer.wrap(FULL_NAME.getBytes());
            column.value = ByteBuffer.wrap("Patrick Rothfuss".getBytes());
            client.insert(ByteBuffer.wrap("prothfuss".getBytes()), columnParent, column, ConsistencyLevel.ONE);
            column.name = ByteBuffer.wrap(BIRTH_DATE.getBytes());
            column.value = ByteBuffer.allocate(8).putLong(1973);
            client.insert(ByteBuffer.wrap("prothfuss".getBytes()), columnParent, column, ConsistencyLevel.ONE);

            column.name = ByteBuffer.wrap(FULL_NAME.getBytes());
            column.value = ByteBuffer.wrap("Howard Tayler".getBytes());
            client.insert(ByteBuffer.wrap("htayler".getBytes()), columnParent, column, ConsistencyLevel.ONE);
            column.name = ByteBuffer.wrap(BIRTH_DATE.getBytes());
            column.value = ByteBuffer.allocate(8).putLong(1968);
            client.insert(ByteBuffer.wrap("htayler".getBytes()), columnParent, column, ConsistencyLevel.ONE);

            column.name = ByteBuffer.wrap(STATE.getBytes());
            column.value = ByteBuffer.wrap("WI".getBytes());
            client.insert(ByteBuffer.wrap("prothfuss".getBytes()), columnParent, column, ConsistencyLevel.ONE);
            column.value = ByteBuffer.wrap("UT".getBytes());
            client.insert(ByteBuffer.wrap("htayler".getBytes()), columnParent, column, ConsistencyLevel.ONE);

            KsDef ks = client.describe_keyspace(KEYSPACE_NAME);
            cfDef = new CfDef(ks.cf_defs.get(0));
            ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap(STATE.getBytes()), "UTF8Type");
            columnDef2.index_type = IndexType.KEYS;
            cfDef.setColumn_metadata(Arrays.asList(columnDef, columnDef1, columnDef2));

            client.system_update_column_family(cfDef);
            Thread.sleep(120000);//give cassandra enough time to build the index.
            client.insert(ByteBuffer.wrap("bsanderson".getBytes()), columnParent, column, ConsistencyLevel.ONE);

            IndexClause indexClause = new IndexClause();
            indexClause.start_key = ByteBuffer.allocate(0);
            IndexExpression indexExpression = new IndexExpression();
            indexExpression.column_name = ByteBuffer.wrap(STATE.getBytes());
            indexExpression.value = ByteBuffer.wrap("UT".getBytes());
            indexExpression.op = IndexOperator.EQ;
            indexClause.addToExpressions(indexExpression);
            SliceRange sliceRange = new SliceRange();
            sliceRange.count = 10;
            sliceRange.start = ByteBuffer.allocate(0);
            sliceRange.finish = ByteBuffer.allocate(0);
            sliceRange.reversed = false;
            SlicePredicate slicePredicate = new SlicePredicate();
            slicePredicate.slice_range = sliceRange;
            List<KeySlice> keys = client.get_indexed_slices(columnParent, indexClause, slicePredicate, ConsistencyLevel.ONE);
            if (!keys.isEmpty()) {
                System.out.println("expecting: bsanderson htayler");
                System.out.print("actual: ");
                for (KeySlice key : keys) {
                    System.out.print(new String(key.getKey()) + " ");
                }
            } else {
                System.out.println("failed to find indexed item");
            }
        } catch (Exception ex) {
            Logger.getLogger(IndexLaterTest.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                client.system_drop_keyspace(KEYSPACE_NAME);
            } catch (Exception ex) {
                Logger.getLogger(IndexLaterTest.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    } finally {
        transport.close();
    }
}

结果如下: -

expecting: bsanderson htayler
actual: bsanderson 

2 个答案:

答案 0 :(得分:1)

出于记录的目的。问题在于以下代码。

ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap(BIRTH_DATE.getBytes()), "LongType");
columnDef1.index_type = IndexType.KEYS;

单独定义index_type是不够的。您还需要设置index_name才能使其正常工作。

答案 1 :(得分:0)

我确实需要一些时间来构建索引。在这种情况下,它应该不到一秒钟,但在您进行查询时可能尚未完成。

创建索引后尝试休眠一到两秒,看看是否会改变结果。