是不允许在Apache Flink Table API

时间:2017-09-16 06:41:37

标签: java apache-flink

我正在尝试在Windows 10上使用Apache Flink 1.3.2和Java 1.8.0_144 IDE Eclipse Mars实现日志分析器。

上下文

  • LogMessage有多种类型。
  • 为每种类型创建POJO。
  • 为每种类型创建POJO类型的DataSet实例。
  • 然后使用表API进行查询,如下所示。

这很好。

DataSet<String> rawLogs = env.readTextFile(input);// input is the data file path
DataSet<FirstBackupMessage> logMsgPOJODataSet = rawLogs.map(new LogMapFunction());
BatchTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env); 
Table LogMessageTable = tableEnv.fromDataSet(logMsgPOJODataSet);
Table result = tableEnv .sql("Select taskId from " + LogMessageTable);
tableEnv.toDataSet(result, Row.class).print();

要求: 我试图使用工厂模型推广这个实现。 为了做到这一点,我尝试将POJO类概括为LogMessage 接口。在上述情况中:

public class FirstBackupMessage implements LogMessage
similarly 
public class SecondBackupMessage implements LogMessage
public class ThirdBackupMessage implements LogMessage

在MapFunction实现中,我填充了特定的类实例,但是map函数的输出被映射到泛型引用,即LogMessage 在上面的情况下,它将是

DataSet<LogMessage> logMsgPOJODataSet = rawLogs.map(new LogMapFunction());  
//the LogMapFunction.map method is populating FirstBackupMessage

之后,如果我尝试查询POJO FirstBackupMessage中的字段,但现在参考接口,即LogMessage 它抛出异常说我找不到的字段。

但是

奇怪的是,如果我使用Generic引用打印DataSet,即logMsgPOJODataSet.print(),它会打印特定POJO中的所有字段,在本例中为FirstBackupMessage。

问题: Flink Table API中不允许/不提供对DataSet的泛型引用的这种转换吗?

1 个答案:

答案 0 :(得分:0)

Table API / SQL库在关系表上运行。通过调用TableEnvironment.fromDataSet(logMsgPOJODataSet)DataSet logMsgPOJODataSet在逻辑上会转换为表格。在此过程中,需要根据logMsgPOJODataSet DataSet的类型识别新表的架构。 Flink的DataSet API使用TypeInformation来确定DataSet的数据类型。

由于logMsgPOJODataSet DataSet的类型为LogMessage,因此Table API不了解其任何子类型。因此,包括LogMessage的所有字段,但没有子类型字段。

在任何情况下,都无法在同一个表中处理不同类型的行。所有行必须具有相同的架构。处理这种情况的两种方法是:

  1. 使架构成为所有子类型的超集,并为不支持的类型提供空值。也许添加另一个表示子类型的字段。
  2. 添加包含所有子类型数据的通用Map<String, String>字段。
  3. 在这两种情况下,转换都需要使用DataSet API完成,例如使用MapFunction