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);