Cassandraのはじめ方─手を動かしてNoSQLを体感しよう

第7回 Cassandraで検索するには[前編]

この記事を読むのに必要な時間:およそ 5.5 分

Cassandraも0.6系がついに0.6.4まで出てきて,stableなリリースとして十分に使えるところまで来ましたね。この連載のコードもすべて0.6系では動作するはずですので,ぜひ最新のものに入れ替えて試してみてください。

前回まででデータの投入,更新,削除までをご紹介しました。今回から複数回に分けて検索を重点的に見ていきましょう。

前準備としてデータを投入しておく

検索メソッドの確認の前準備として,まずデータの投入を行います。今回はシンプルな郵便番号のデータを利用します。以下のURLから東京都のデータを取得して,解凍後,データを投入してください。

郵便番号データのダウンロード:日本郵便
URL:http://www.post.japanpost.jp/zipcode/dl/kogaki/lzh/13tokyo.lzh

データは説明のため簡易的なデータ構造とします。

  • キーは郵便番号
  • データは,郵便番号(postalCode)⁠あて先(address)⁠あて先読み方(addressYomi)の3つ
  • スーパーカラムは使わない

データを投入するコードは以下のとおりです。

リスト1 SimpleAddressInsert.java(一部抜粋)

Cassandra.Client client = new Cassandra.Client(protocol);
long timestamp = System.currentTimeMillis();

Map<String, Map<String, List<Mutation>>> map = new HashMap<String, Map<String, List<Mutation>>>();

is = Thread.currentThread().getContextClassLoader()
		.getResourceAsStream("13TOKYO.CSV");
BufferedReader reader = new BufferedReader(new InputStreamReader(
		is, "MS932"));
String line = null;
while ((line = reader.readLine()) != null) {
	List mutations = new ArrayList();
	String[] lines = line.split(",");
	String postalCode = removeQuote(lines[2]);
	String addressYomi = buildAddressYomi(lines);
	String address = buildAddress(lines);
	System.out.println(postalCode + " " + addressYomi + " "
			+ address);
	{
		Mutation mutation = new Mutation();
		ColumnOrSuperColumn csc = new ColumnOrSuperColumn();
		csc.setColumn(new Column("postalCode".getBytes(),
				postalCode.getBytes(), timestamp));
		mutation.setColumn_or_supercolumn(csc);
		mutations.add(mutation);
	}
	{
		Mutation mutation = new Mutation();
		ColumnOrSuperColumn csc = new ColumnOrSuperColumn();
		csc.setColumn(new Column("address".getBytes(), address
				.getBytes(), timestamp));
		mutation.setColumn_or_supercolumn(csc);
		mutations.add(mutation);
	}
	{
		Mutation mutation = new Mutation();
		ColumnOrSuperColumn csc = new ColumnOrSuperColumn();
		csc.setColumn(new Column("addressYomi".getBytes(),
				addressYomi.getBytes(), timestamp));
		mutation.setColumn_or_supercolumn(csc);
		mutations.add(mutation);
	}
	Map<String, List<Mutation>> mutmap = new HashMap<String, List<Mutation>>();
	mutmap.put(COLUMN_FAMILY, mutations);
	map.put(new String(postalCode), mutmap);
	count++;
}
client.batch_mutate(KEYSPACE, map, ConsistencyLevel.ONE);
reader.close();

設定ファイル(storage-conf.xml)には以下のように指定します。場所はCassandraのデフォルト設定であるキースペースのKeyspace1以下になります。

リスト2 storage-conf.xml

<ColumnFamily Name="SimpleAddress" CompareWith="UTF8Type" />

実行してデータを投入します。以下のようになるはずです。

...
1002100 トウキョウト オガサワラムラ  東京都 小笠原村 
1002101 トウキョウト オガサワラムラ チチジマ 東京都 小笠原村 父島
1002211 トウキョウト オガサワラムラ ハハジマ 東京都 小笠原村 母島
3654件インサート完了.

このデータをサンプルとして,検索メソッドを使ってみましょう。

単一カラムを取得するには

まずは1件検索してみましょう。Cassandraではgetメソッドを使います。getメソッドは以下のようなAPIになっています。

ColumnOrSuperColumn get(キースペース, キー, ColumnPath, ConsistencyLevel)

コードは以下のようになります。この例では郵便番号⁠1006528⁠の住所を検索しています。

リスト3 SimpleAddressSearchOne.java

Cassandra.Client client = new Cassandra.Client(protocol);
ColumnPath path = new ColumnPath(COLUMN_FAMILY);
path.setColumn("address".getBytes());//検索するカラム名を指定

ColumnOrSuperColumn csc = client.get(KEYSPACE, "1006528", path,
		ConsistencyLevel.ONE);
Column c = csc.getColumn();
String name = new String(c.getName());
String value = new String(c.getValue());

System.out.println(name + " -> " + value + "(" + c.getTimestamp()
		+ ")");

結果は以下のようになります。

address -> 東京都 千代田区 丸の内新丸の内ビルディング(28階)(1281276409219)

第5回でも説明したように,カラムファミリとカラムの位置はColumnPathで特定します。今回のサンプルでは,カラムファミリとカラムのケースなので,検索するカラム名を指定します。

今回のサンプルではありませんが,スーパーカラムの場合は上記に加えて,以下のようにしてスーパーカラム名を指定する必要があります。

ColumnPath path = new ColumnPath(COLUMN_FAMILY);
path.setSuper_column(LongUtil.toByteArray(1006528L));//スーパーカラムを指定
path.setColumn("address".getBytes());//カラム名を指定

また戻り値のColumnOrSuperColumnからデータをどのように取得するかは,カラムまたはスーパーカラムで取得方法が異なります。

カラムの場合
→ColumnOrSuperColumn#getColumn()でカラムを取得
スーパーカラムの場合
→ColumnOrSuperColumn#getSuperColumn()#getColumns()でスーパーカラム内のカラムを取得

著者プロフィール

大谷晋平(おおたにしんぺい)

オープンソースプログラマ。WebフレームワークT2の開発をしながらHadoop/NoSQLミドルウェアにも手を出す。最近ではもっぱらHadoop,Cassandra,Avro,kumofsなどに興味津々。

blog:http://d.hatena.ne.jp/shot6/

Twitter:http://twitter.com/shot6/

コメント

コメントの記入