さくらVPSでApache Cassandra 0.7のSecondary indexesを利用してみる
Cassandra 0.7で実装されたSecondary indexesを試してみた。「cassandra-cli」上で動作するかまずは試してみる。
参考にしたのは、「DataStax:What's new in Cassandra 0.7: Secondary indexes」と「λab's Blog:Cassandra0.7.0のSecondary indexesを使用したJava APIサンプル」を参考にしました。
テスト用のkeyspaceを作成する
まずは、テスト用の「keyspace」と「column family」を作成する。
create keyspace test2; use test2; create column family users with comparator=UTF8Type and column_metadata=[{column_name:full_name, validation_class:UTF8Type},{column_name:birth_date, validation_class:LongType, index_type:KEYS}];
「column_name:birth_date」で「index_type:KEYS」と指定しています。*1
テストデータを作成する
テストデータを投入する為のプログラムを作成。
テストデータは、2件用意した。
No | full_name | birth_date |
---|---|---|
1 | takahashimaiko | 1985 |
2 | yamamotoyuuki | 1987 |
「batch_mutate」メソッドで二件挿入した。
// カラムファミリ名 String cfName = "users"; // key と カラムファミリの Map の Map を作成 Map<ByteBuffer, Map<String, List<Mutation>>> mutaionMap = new HashMap<ByteBuffer, Map<String, List<Mutation>>>(); // レコードを挿入 long timestamp = System.currentTimeMillis(); long birthday1 = 1985; long birthday2 = 1987; // 登録・更新したい値から Mutation オブジェクトの List を作成 List<Mutation> columns = new ArrayList<Mutation>(); columns.add(toMutation("full_name", "takahashimaiko", timestamp)); columns.add(toMutation("birth_date", FBUtilities.toByteBuffer(birthday1), timestamp)); List<Mutation> columns2 = new ArrayList<Mutation>(); columns2.add(toMutation("full_name", "yamamotoyuuki", timestamp)); columns2.add(toMutation("birth_date", FBUtilities.toByteBuffer(birthday2), timestamp)); // カラムファミリと Mutation のリストの Map を作成 Map<String, List<Mutation>> innerMap = new HashMap<String, List<Mutation>>(); Map<String, List<Mutation>> innerMap2 = new HashMap<String, List<Mutation>>(); innerMap.put(cfName, columns); innerMap2.put(cfName, columns2); // 取り合えず同じ内容を key だけ別にして追加。 mutaionMap.put(ByteBuffer.wrap("takahashimaiko".getBytes("UTF-8")), innerMap); mutaionMap.put(ByteBuffer.wrap("yamamotoyuuki".getBytes("UTF-8")), innerMap2); client.batch_mutate(mutaionMap, ConsistencyLevel.ONE); showData(client); port.close(); /** * カラム名、値、タイムスタンプ値 から Mutation オブジェクトを生成する。 * @param name * @param value * @param timestamp * @return * @throws UnsupportedEncodingException */ public static Mutation toMutation(final String name, final String value, final long timestamp) throws UnsupportedEncodingException { System.out.printf("カラム名:[%s] 値:[%s] タイムスタンプ:[%s]", name, value, timestamp); System.out.println(" "); Mutation mutation = new Mutation(); ColumnOrSuperColumn csc = new ColumnOrSuperColumn(); csc.setColumn(new Column(ByteBuffer.wrap(name.getBytes("UTF-8")), ByteBuffer.wrap(value.getBytes("UTF-8")), timestamp)); mutation.setColumn_or_supercolumn(csc); return mutation; } /** * カラム名、値、タイムスタンプ値 から Mutation オブジェクトを生成する。 * @param name * @param value * @param timestamp * @return * @throws UnsupportedEncodingException */ public static Mutation toMutation(final String name, final ByteBuffer value, final long timestamp) throws UnsupportedEncodingException { System.out.printf("カラム名:[%s] 値:[%s] タイムスタンプ:[%s]", name, value, timestamp); System.out.println(" "); Mutation mutation = new Mutation(); ColumnOrSuperColumn csc = new ColumnOrSuperColumn(); csc.setColumn(new Column(ByteBuffer.wrap(name.getBytes("UTF-8")), value, timestamp)); mutation.setColumn_or_supercolumn(csc); return mutation; }
念のため、挿入したテストデータを確認する。
[default@test2] list users; Using default limit of 100 ------------------- RowKey: yamamotoyuuki => (column=birth_date, value=1987, timestamp=1295249913049) => (column=blood, value=B, timestamp=1295249913049) => (column=full_name, value=yamamotoyuuki, timestamp=1295249913049) ------------------- RowKey: takahashimaiko => (column=birth_date, value=1985, timestamp=1295249913049) => (column=blood, value=A, timestamp=1295249913049) => (column=full_name, value=takahashimaiko, timestamp=1295249913049) 2 Rows Returned.
where句を試してみる
「birth_date」が「1985」のデータを取得する。
[default@test2] get users where birth_date = 1985; ------------------- RowKey: takahashimaiko => (column=birth_date, value=1985, timestamp=1295249913049) => (column=blood, value=A, timestamp=1295249913049) => (column=full_name, value=takahashimaiko, timestamp=1295249913049) 1 Row Returned.
動的にセカンダリインデックス追加
下記の通り、動的にセカンダリインデックス追加。
update column family users with comparator=UTF8Type and column_metadata=[{column_name:full_name, validation_class:UTF8Type},{column_name:birth_date, validation_class:LongType, index_type:KEYS},{column_name:blood, validation_class:UTF8Type, index_type:KEYS}];
「column_name:blood」を増やしたので、テストデータを再度追加する。
下記の形でアクセスすることができた。
[default@test2] get users where blood = 'A'; ------------------- RowKey: takahashimaiko => (column=birth_date, value=1985, timestamp=1295249913049) => (column=blood, value=A, timestamp=1295249913049) => (column=full_name, value=takahashimaiko, timestamp=1295249913049) 1 Row Returned.
とりあえず、参考ページと同じことを確認することができました。
*1: index_typeにどんなものがあるか不明