Get
次はGetです。GetはHBaseからRow単位のデータを取得するAPIです。以下が、Getのコードになります。
byte[] fam = Bytes.toBytes("fam");
byte[] row = Bytes.toBytes("row");
byte[] col1 = Bytes.toBytes("col1");
byte[] col2 = Bytes.toBytes("col2");
// Getオブジェクトを生成する際にRowKeyを指定
Get get = new Get(row);
// データをGetする
Result result = table.get(get);
System.out.println(Bytes.toString(result.getValue(fam, col1))); // val1
System.out.println(Bytes.toString(result.getValue(fam, col2))); // val2
ResultオブジェクトはRow単位の結果です。getValueでValueを取得しています。今回は省略しますが、ResultはgetValue以外にもさまざまなデータの取得メソッドが用意されています。
以下のようにColumnFamilyを限定することで、I/Oの切り分けが可能になります。
// ColumnFamilyを限定 get.addFamily(fam);
取得するColumnを限定したい場合は、以下のようにします。
// Columnを限定 get.addColumn(fam, col1);
複数バージョンを取得したい場合は、以下のようにします。デフォルトは1なので最新バージョンのみ取得します。
// 3バージョン取得 get.setMaxVersions(3);
また、以下のメソッドを用いることで、特定のTimestampやその範囲を指定して取得できます。
// Timestamp指定 get.setTimeStamp(ts); // Timestampの範囲を指定 get.setTimeRange(minTs, maxTs);
Delete
次はDeleteです。
byte[] row = Bytes.toBytes("row");
Delete delete = new Delete(row);
table.delete(delete);
上記のコードでは、RowKeyが"row"のRowをまるごと削除しています。削除の範囲を特定のColumnFamilyに絞りたい場合は、以下のようにします。
delete.deleteFamily(fam);
次に、削除の範囲を特定のColumnに絞りたい場合は、以下のようにします。
delete.deleteColumns(fam, col1);
削除の範囲を特定のColumnで最新のバージョンに絞りたい場合は、以下のようにします。
delete.deleteColumn(fam, col1);
batchとRowMutations
複数の処理を一度に行いたい場合に、batchとRowMutationsがあります。batchは複数Rowに対する操作を、RowMutationsは単一Rowに対する操作を一度に行うことができます。
batchの例は以下のようになります。PutとDeleteを一度に行っています。
byte[] row1 = Bytes.toBytes("row1");
byte[] row2 = Bytes.toBytes("row2");
byte[] fam = Bytes.toBytes("fam");
byte[] col1 = Bytes.toBytes("col1");
byte[] val1 = Bytes.toBytes("val1");
byte[] row3 = Bytes.toBytes("row3");
Put put1 = new Put(row1);
put.add(fam, col1, val1);
Put put2 = new Put(row2);
put.add(fam, col1, val1);
Delete delete = new Delete(row3);
List<Row> actions = new ArrayList<Row>();
actions.add(put1);
actions.add(put2);
actions.add(delete);
// バッチ処理
table.batch(actions);
また、以下のように、複数のGetもbatchによって一度に行うことができます。
byte[] row1 = Bytes.toBytes("row1");
byte[] row2 = Bytes.toBytes("row2");
byte[] fam = Bytes.toBytes("fam");
byte[] col = Bytes.toBytes("col");
Get get1 = new Get(row1);
Get get2 = new Get(row2);
List<Row> actions = new ArrayList<Row>();
actions.add(get1);
actions.add(get2);
// バッチ処理
Object[] results = table.batch(actions);
System.out.println(((Result) results[0]).getValue(fam, col)); // get1の結果
System.out.println(((Result) results[1]).getValue(fam, col)); // get2の結果
batchの結果としてObjectの配列が返ってきますが、actionsに指定した操作の結果が入っています。Getの結果としてはResultオブジェクトが返ってくるので、キャストして使用することができます。
RowMutationsの例は以下のようになります。この処理はアトミックに行われます。
byte[] fam = Bytes.toBytes("fam");
byte[] row = Bytes.toBytes("row");
byte[] col1 = Bytes.toBytes("col1");
byte[] val1 = Bytes.toBytes("val1");
byte[] col2 = Bytes.toBytes("col2");
RowMutations rm = new RowMutations(row);
Put put = new Put(row);
put.add(fam, col1, val1);
rm.add(put);
Delete delete = new Delete(row);
delete.deleteColumns(fam, col2);
rm.add(delete);
// バッチ処理(アトミックに処理される)
table.mutateRow(rm);
上記のコードでは、PutとDeleteがアトミックに行われます。
Scan
Scanは複数Rowにまたがったデータを取得するAPIで、カーソルのような操作を行うことができます。
byte[] fam = Bytes.toBytes("fam");
byte[] col = Bytes.toBytes("col");
byte[] startRow = Bytes.toBytes("row1");
byte[] stopRow = Bytes.toBytes("row5");
Scan scan = new Scan();
scan.setStartRow(startRow);
scan.setStopRow(stopRow);
// ResultScannerを取得
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
// 各RowのValueを取得
byte[] value = result.getValue(fam, col);
}
// 最後にclose
scanner.close();
Scanオブジェクトを生成し、ScanしたいRowのstartRowとstopRowを指定しています。stopRowはScanする対象に含まれないので注意してください。
生成したScanオブジェクトをHTableのgetScannerに渡すことで、ResultScannerオブジェクトが返ってきます。
ResultScannerはIterableを実装しているので拡張forに渡すことができ、結果のResultオブジェクトを受け取ることができます。
scannerは使い終わったらcloseします。
ScanはResultScannerを取得した時点のデータが取れることが保証されています。
つまり、ResultScannerを取得した後にデータが変更されても、変更前のデータが取得できます。
ScanもGetと同様、ColumnFamilyやColumnを限定したり、バージョン数やTimestampの指定やその範囲の指定ができます。
// ColumnFamilyを限定 scan.addFamily(fam); // Columnを限定 scan.addColumn(fam, col1); // 3バージョン取得 scan.setMaxVersions(3); // Timestamp指定 scan.setTimeStamp(ts); // Timestampの範囲を指定 scan.setTimeRange(minTs, maxTs);
