如何从PCollection <String>创建PCollection <Row>以执行Beam SQL Trasforms

时间:2019-07-05 08:10:23

标签: java join apache-kafka apache-beam

我正在尝试实现一个数据管道,该管道将来自Kafka主题的多个不受限制的源结合在一起。我能够连接到主题并以PCollection<String>的形式获取数据,我需要将其转换为PCollection<Row>。我将逗号分隔的字符串拆分为一个数组,并使用架构将其转换为Row。但是,如何实现/构建模式并动态绑定值?

即使我创建了一个单独的用于架构构建的类,也有办法将字符串数组直接绑定到架构吗?

下面是我当前的工作代码,它是静态的,每当我建立管道时都需要重写,并且它也会根据字段数而延长。

final Schema sch1 =
                Schema.builder().addStringField("name").addInt32Field("age").build();

PCollection<KafkaRecord<Long, String>> kafkaDataIn1 = pipeline
  .apply(
    KafkaIO.<Long, String>read()
      .withBootstrapServers("localhost:9092")
      .withTopic("testin1")
      .withKeyDeserializer(LongDeserializer.class)
      .withValueDeserializer(StringDeserializer.class)
      .updateConsumerProperties(
         ImmutableMap.of("group.id", (Object)"test1")));

PCollection<Row> Input1 = kafkaDataIn1.apply(
  ParDo.of(new DoFn<KafkaRecord<Long, String>, Row>() {
    @ProcessElement
    public void processElement(
        ProcessContext processContext,
        final OutputReceiver<Row> emitter) {

          KafkaRecord<Long, String> record = processContext.element();
          final String input = record.getKV().getValue();

          final String[] parts = input.split(",");

          emitter.output(
            Row.withSchema(sch1)
               .addValues(
                   parts[0],
                   Integer.parseInt(parts[1])).build());
        }}))
  .apply("window",
     Window.<Row>into(FixedWindows.of(Duration.standardSeconds(50)))
       .triggering(AfterWatermark.pastEndOfWindow())
       .withAllowedLateness(Duration.ZERO)
       .accumulatingFiredPanes());

Input1.setRowSchema(sch1);

我的期望是以动态/可重用的方式实现与上述代码相同的事情。

1 个答案:

答案 0 :(得分:1)

该模式是在pcollection上设置的,因此它不是动态的,如果要延迟构建它,则需要使用支持它的格式/编码器。 Java序列化或json是示例。

据说可以从sql功能中受益,您还可以将静态模式与查询字段和其他字段一起使用,这样,静态部分就可以执行sql,并且不会丢失附加数据。

罗曼