ここと同じモデルを使います。
get users where birth_date > 1000 and blood = 'A'
相当の処理をJavaで実装します。
セカンダリインデックスによるカラム値の範囲検索にはget_indexed_slices
メソッドを使います。get_range_slices
とよく似ています。(実際にこのページのMain4をコピペしました。)
CLIでまず試す
[default@demo] get users where birth_date > 1000 and blood = 'A';
-------------------
RowKey: xxx
=> (column=birth_date, value=1999, timestamp=1294946222506)
=> (column=blood, value=A, timestamp=1294946222506)
=> (column=full_name, value=Taro Yamada, timestamp=1294946222506)
-------------------
RowKey: hoge
=> (column=birth_date, value=2000, timestamp=1294945329023)
=> (column=blood, value=A, timestamp=1294945329023)
=> (column=full_name, value=Hogeo Hoge, timestamp=1294945329023)
2 Rows Returned.
Javaで実装
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import org.apache.cassandra.thrift.Cassandra;
import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.ColumnOrSuperColumn;
import org.apache.cassandra.thrift.ColumnParent;
import org.apache.cassandra.thrift.ConsistencyLevel;
import org.apache.cassandra.thrift.IndexClause;
import org.apache.cassandra.thrift.IndexExpression;
import org.apache.cassandra.thrift.IndexOperator;
import org.apache.cassandra.thrift.KeySlice;
import org.apache.cassandra.thrift.SlicePredicate;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
public class SecondaryIndexSample1 {
public static final String CHARSET = "UTF-8";
public static void main(String[] args) throws Exception {
TTransport transport = new TSocket("localhost", 9160);
TFramedTransport tf = new TFramedTransport(transport);
TProtocol proto = new TBinaryProtocol(tf);
Cassandra.Client client = new Cassandra.Client(proto);
transport.open();
try {
// キースペース名
String ksName = "demo";
// カラムファミリ名
String cfName = "users";
client.set_keyspace(ksName);
SlicePredicate predicate = new SlicePredicate();
predicate.setColumn_names(Arrays.asList(buffer("full_name"),
buffer("blood")));
ColumnParent parent = new ColumnParent(cfName);
// get users where birth_date > 2000 and blood = 'A' 相当
IndexClause clause = new IndexClause();
clause.setStart_key(new byte[0]);
clause.setExpressions(Arrays.asList(
new IndexExpression(buffer("birth_date"), IndexOperator.GT,
FBUtilities.toByteBuffer(1000L)),
new IndexExpression(buffer("blood"), IndexOperator.EQ,
buffer("A"))));
List<KeySlice> results = client.get_indexed_slices(parent, clause,
predicate, ConsistencyLevel.ONE);
System.out.println("----------");
for (KeySlice keySlice : results) {
List<ColumnOrSuperColumn> coscs = keySlice.getColumns();
for (ColumnOrSuperColumn cosc : coscs) {
Column column = cosc.getColumn();
System.out.printf("%s=%s%n", new String(column.getName(),
CHARSET), new String(column.getValue(), CHARSET));
}
System.out.println("----------");
}
} finally {
transport.close();
}
}
public static ByteBuffer buffer(String value)
throws UnsupportedEncodingException {
return ByteBuffer.wrap(value.getBytes(CHARSET));
}
}
実行結果
----------
blood=A
full_name=Taro Yamada
----------
blood=A
full_name=Hogeo Hoge
----------
0.7.0
では範囲検索する場合、他のセカンダリインデックスをもつカラム値を指定しないといけないことに注意(birth_date > 1000
だけだはエラーになる。)