2

HBase に値として格納する複雑な Avro レコード (ネストされたレコード、unioned 型) があります。現在、ファイルのライター スキーマと HBase にあるレコードに一致するスキーマを使用して、Avro データ ファイルを読み取ります。

Schema schema = new Schema.Parser().parse(schema_file);
DatumReader<GenericRecord> datumReader = new SpecificDatumReader<GenericRecord>(schema);
DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(avro_file, datumReader);
GenericRecord record = null;
record = dataFileReader.next(record);

次に、HBase をチェックして、同じ行キーを持つレコードが既に存在するかどうかを確認します。get によって返される val は、Avro レコードのバイト配列表現です。

Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "table");
String pk = new String(record.get("x").toString()+record.get("y").toString());
Get get = new Get(Bytes.toBytes(pk));
Result result = table.get(get);
byte[] val = result.getValue(Bytes.toBytes("c"),Bytes.toBytes("c"));

HBase に同じ行キーを持つレコードがない場合は、次の場所にレコードを配置します。

if (val == null) {
  System.out.println("pk: "+pk+" does not exist");
  Put put = new Put(Bytes.toBytes(pk));
  put.add(Bytes.toBytes("c"), Bytes.toBytes("c"), Bytes.toBytes(record.toString()));
  try {
    table.put(put);
  } catch (Exception e) {
    System.err.println("Can't put to table: " + e);
  }
}
else {
  System.out.println("pk: "+pk+" does exist");
  //help me!
}

HBase に同じ行キーを持つレコードがある場合、HBase の結果のバイト配列を Avro スキーマに変換し直し、いくつかのフィールドを比較して、どのレコードが「より良い」かを確認します。「より良い」レコードを HBase に入れたいのですが、行き詰まっています。バイト配列を HBase から GenericRecord に変換して、自分のファイル レコードと HBase レコードの間でフィールドを比較するにはどうすればよいですか?

4

1 に答える 1

4

私はそれを考え出した。バイト配列に変換された文字列ではなく、シリアル化されたバイト配列としてレコードを HBase に書き込む必要がありました。

プットは次のようになります。

ByteArrayOutputStream baos = new ByteArrayOutputStream();
DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
DataFileWriter<GenericRecord> dfw = new DataFileWriter<GenericRecord>(writer);
dfw.create(schema, baos);
dfw.append(record);
dfw.close();
Put put = new Put(Bytes.toBytes(pk));
put.add(Bytes.toBytes("c"), Bytes.toBytes("c"), baos.toByteArray());

そして、これを取得するには:

 GenericRecord hrecord = null;
    ByteArrayInputStream bais = new ByteArrayInputStream(val);
    DataFileStream<GenericRecord> dfs = new DataFileStream<GenericRecord>(bais, datumReader);
    hrecord = dfs.next(hrecord);
于 2013-06-29T11:46:11.407 に答える