2

Avro に、値が 、 、 などの単純なキーと値のペアがあるfloatdoubleしますintstring

{"namespace": "com.namespace.kafka.event",
 "type": "record",
 "name": "RecordName",
 "fields": [
    {"name": "key", "type": "String"},
    {"name": "value", "type": "Any/Object/Bytes???"}
 ]
}

これを Avro で表現する最良の方法は何ですか?

  1. Scalaで何らかの形で逆シリアル化されたバイト配列を持ち、型を推測するか、メタデータを含む別の値フィールドを追加します
  2. 値を入力するプリミティブ タイプごとにカスタム レコード タイプを作成し、Avro で汎用レコード解析を使用する
  3. 表現したいプリミティブ値の型ごとにキーと値のペアを作成します。

もう 1 つの問題は、これを Scala でどのように表現するかです。Any 型を持つのは面倒です。どこでも型テストを行うよりも、数値などの型を知る方がはるかに優れています...

4

2 に答える 2

2

avro4sを使用しているEither[A,B]場合、タイプが 2 つしかない場合は を使用できます。ケースクラスを定義して、次のようにいずれかを含めます。

case class Moo(either: Either[String, BigDecimal])

次に、そのスキーマを作成できます。

val schema = Schemafor[Moo]

またはデータを書き出す:

val moo1 = Moo(Left("moo1"))
val moo2 = Moo(Right(12.3))

val output = new ByteArrayOutputStream
val avro = AvroOutputStream.data[Moo](output)
avro.write(moo1, moo2)
avro.close()

そして、データを読み込みます:

val in = AvroInputStream.data[Moo](bytes)
val moos = in.iterator.toList
in.close()

タイプが 2 つ以上ある場合は、 Shapeless の Coproduct を使用できます。ケースクラスは次のようになります。

case class Moo(coproduct: String :+: BigDecimal :+: CNil)

shapeless の coproduct 構文に慣れていない場合、最初に見たときは少し変わっていますが、中置スタイルを使用して型を組み合わせているだけで、 +:+ は実際には型の名前::です標準 scala の空でないリストの名前。

次のようにインスタンスを作成します。

val moo1 = Moo(Coproduct[String]("moo1"))
val moo2 = Moo(Coproduct[BigDecimal](12.3))

あとは同じです。

さらなる例については、avro4s の単体テストを参照してください。

于 2016-09-12T22:12:29.910 に答える
1

Avro の Union DataTypes を使ってみることはできますか?

https://avro.apache.org/docs/1.8.1/spec.html#Unions

于 2016-09-12T04:06:06.497 に答える