将GenericData.Record字段分别编码为编码密钥

时间:2016-05-01 12:29:51

标签: avro

我正在尝试使用Avro来编码键/值对,但是无法弄清楚如何在schema / GenericData.Record中编码单个字段以便生成密钥。

采用这个简单的架构:

{"name":"TestRecord", "type":"record", "fields":[
  {"name":"id", "type":"long"},
  {"name":"name", "type":"string"},
  {"name":"desc", "default":null, "type":["null","string"]}
]}

我正在编码这样的记录:

val testRecordSchema = schemaParser.parse(testRecordSchemaString)
val writer = new GenericDatumWriter[GenericRecord](testRecordSchema)
val baos = new ByteArrayOutputStream()
val encoder = EncoderFactory.get().binaryEncoder(baos, null)
val record = new org.apache.avro.generic.GenericData.Record(schema)
record.put("id", 1L)
record.put("name", "test")
writer.write(record, encoder)
encoder.flush

但现在说我想单独编码id字段,用作密钥,我想按名称进行编码,因为有时候我想用name字段作为密钥而不是id

我尝试了GenericDatumWriter的多个排列。 GenericDatumWriter有一个名为writeField的方法看起来很有希望,但它是protected。否则看起来你必须写完整的记录。

我可以将我的字段包装在新模式中定义的新记录类型中,例如:

{"name":"TestRecordKey", "type":"record", "fields":[
  {"name":"id", "type":"long"}
]}

我100%确定我可以做到这一点,但是我必须创建一个新的记录类型并为每个关键字段管理它。这不是次要的,看起来应该有一些更简单的方法来做到这一点。

1 个答案:

答案 0 :(得分:0)

事实证明,创建一个只有一个字段的新记录类型架构并不困难 - 我想用作关键字段,就像我上面的例子一样:

{"name":"TestRecordKey", "type":"record", "fields":[
  {"name":"id", "type":"long"}
]}

我在动态执行此操作,因为我使用有效负载模式初始化Schema.Parser - 我只是以编程方式基于有效负载模式创建密钥模式。

希望不那么长时间的解决方案,但这有效。我仍然会投票并接受任何更清洁的解决方案。