How to programatically add index to Cassandra 0.7

核能气质少年 提交于 2020-01-04 02:27:26

问题


I tried to run the demo on http://www.riptano.com/blog/whats-new-cassandra-07-secondary-indexes programatically, but the results are different from running it in CLI. It seems like Cassandra can only index columns after index is added. All previous data are left unindexed.

Full source code are as below:-

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

The results are :-

expecting: bsanderson htayler
actual: bsanderson 

回答1:


For the purpose of record. The problem lies in the following code.

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

Defining the index_type alone is not enough. You need to set a index_name as well for it to work.




回答2:


I does take some time for the index to be built. It should take less than a second in this case, but it might not have completed by the time you make the query.

Try sleeping for one or two seconds after creating the index and see if that changes the results.



来源:https://stackoverflow.com/questions/4677057/how-to-programatically-add-index-to-cassandra-0-7

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