访问 AVRO GenericRecord 中的嵌套字段 (Java/Scala)
Accessing nested fields in AVRO GenericRecord (Java/Scala)
我有一个带有嵌套字段的 GenericRecord。当我使用 genericRecord.get(1)
时,它 returns 一个包含嵌套 AVRO 数据的对象。
我希望能够像 genericRecord.get(1).get(0)
那样访问该对象,但我不能,因为 AVRO returns 一个对象。
有解决这个问题的简单方法吗?
当我执行类似 returnedObject.get("item")
的操作时,它会显示 item not a member of returnedObject
。
我想出了一个办法。将返回的 Object
转换为 GenericRecord
.
示例(scala):
val data_nestedObj = (data.get("nestedObj")).asInstanceOf[GenericRecord]
然后我可以通过以下方式访问新 GenericRecord 中的嵌套字段:
data_nestedObj.get("nestedField")
这对我来说效果很好。
您可以使用 avro 序列化库来帮助您。例如https://github.com/sksamuel/avro4s(我是作者)但还有其他人
您只需为要获取的数据类型定义一个案例 class,这可以包括嵌套案例 classes。例如,
case class Boo(d: Boolean)
case class Foo(a: String, b: Int, c: Boo)
然后创建 RecordFormat 类型的实例class。
val format = RecordFormat[Foo]
最后,您可以使用它来提取记录或创建记录。
val record = format.to(someFoo)
或
val foo = format.from(someRecord)
@rye 的回答是正确的并且工作正常,但如果你可以避免使用 asInstanceOf
那么你应该。所以我写了下面的方法来检索嵌套字段。
/**
* Get the value of the provided property. If the property contains `.` it assumes the property is nested and
* parses the avroRecord with respective number of nested levels and retrieves the value at that level.
*/
def getNestedProperty(property: String, avroRecord: GenericRecord): Option[Object] = {
val tokens = property.split("\.")
tokens.foldLeft[Tuple2[GenericRecord, Option[Object]]]((avroRecord,None)){(tuple, token) =>
tuple._1.get(token) match {
case value: GenericRecord =>
(value, tuple._2)
case value @ (_:CharSequence | _:Number | _: ByteBuffer) =>
(tuple._1, Option(value))
case _ =>
(tuple._1, None)
}
}._2
}
我有一个带有嵌套字段的 GenericRecord。当我使用 genericRecord.get(1)
时,它 returns 一个包含嵌套 AVRO 数据的对象。
我希望能够像 genericRecord.get(1).get(0)
那样访问该对象,但我不能,因为 AVRO returns 一个对象。
有解决这个问题的简单方法吗?
当我执行类似 returnedObject.get("item")
的操作时,它会显示 item not a member of returnedObject
。
我想出了一个办法。将返回的 Object
转换为 GenericRecord
.
示例(scala):
val data_nestedObj = (data.get("nestedObj")).asInstanceOf[GenericRecord]
然后我可以通过以下方式访问新 GenericRecord 中的嵌套字段:
data_nestedObj.get("nestedField")
这对我来说效果很好。
您可以使用 avro 序列化库来帮助您。例如https://github.com/sksamuel/avro4s(我是作者)但还有其他人
您只需为要获取的数据类型定义一个案例 class,这可以包括嵌套案例 classes。例如,
case class Boo(d: Boolean)
case class Foo(a: String, b: Int, c: Boo)
然后创建 RecordFormat 类型的实例class。
val format = RecordFormat[Foo]
最后,您可以使用它来提取记录或创建记录。
val record = format.to(someFoo)
或
val foo = format.from(someRecord)
@rye 的回答是正确的并且工作正常,但如果你可以避免使用 asInstanceOf
那么你应该。所以我写了下面的方法来检索嵌套字段。
/**
* Get the value of the provided property. If the property contains `.` it assumes the property is nested and
* parses the avroRecord with respective number of nested levels and retrieves the value at that level.
*/
def getNestedProperty(property: String, avroRecord: GenericRecord): Option[Object] = {
val tokens = property.split("\.")
tokens.foldLeft[Tuple2[GenericRecord, Option[Object]]]((avroRecord,None)){(tuple, token) =>
tuple._1.get(token) match {
case value: GenericRecord =>
(value, tuple._2)
case value @ (_:CharSequence | _:Number | _: ByteBuffer) =>
(tuple._1, Option(value))
case _ =>
(tuple._1, None)
}
}._2
}