---
title: Cassandra0.7.0のSecondary indexesを使用したJava APIサンプル
tags: []
categories: ["Middleware", "NoSQL", "Cassandra"]
date: 2011-01-13T19:15:15Z
updated: 2011-01-13T19:15:15Z
---

[ここ][1]と同じモデルを使います。

`get users where birth_date > 1000 and blood = 'A'`相当の処理をJavaで実装します。

セカンダリインデックスによるカラム値の範囲検索には`get_indexed_slices`メソッドを使います。`get_range_slices`とよく似ています。(実際に[このページのMain4][2]をコピペしました。)


### 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`だけだはエラーになる。)


  [1]: http://blog.ik.am/entry/view/id/51/title/Cassandra0.7.0%E3%81%AESecondary+indexes%E3%82%92%E8%A9%A6%E3%81%99/
  [2]: http://blog.ik.am/entry/view/id/52/title/Cassandra0.7.0%E3%81%AEJava+API%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB/
