我尝试以编程方式在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
答案 0 :(得分:1)
出于记录的目的。问题在于以下代码。
ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap(BIRTH_DATE.getBytes()), "LongType");
columnDef1.index_type = IndexType.KEYS;
单独定义index_type是不够的。您还需要设置index_name才能使其正常工作。
答案 1 :(得分:0)
我确实需要一些时间来构建索引。在这种情况下,它应该不到一秒钟,但在您进行查询时可能尚未完成。
创建索引后尝试休眠一到两秒,看看是否会改变结果。