我正在尝试使用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%确定我可以做到这一点,但是我必须创建一个新的记录类型并为每个关键字段管理它。这不是次要的,看起来应该有一些更简单的方法来做到这一点。
答案 0 :(得分:0)
事实证明,创建一个只有一个字段的新记录类型架构并不困难 - 我想用作关键字段,就像我上面的例子一样:
{"name":"TestRecordKey", "type":"record", "fields":[
{"name":"id", "type":"long"}
]}
我在动态执行此操作,因为我使用有效负载模式初始化Schema.Parser
- 我只是以编程方式基于有效负载模式创建密钥模式。
希望不那么长时间的解决方案,但这有效。我仍然会投票并接受任何更清洁的解决方案。