我正在尝试在Windows 10上使用Apache Flink 1.3.2和Java 1.8.0_144 IDE Eclipse Mars实现日志分析器。
上下文
这很好。
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的泛型引用的这种转换吗?
答案 0 :(得分:0)
Table API / SQL库在关系表上运行。通过调用TableEnvironment.fromDataSet(logMsgPOJODataSet)
,DataSet
logMsgPOJODataSet
在逻辑上会转换为表格。在此过程中,需要根据logMsgPOJODataSet
DataSet
的类型识别新表的架构。 Flink的DataSet API使用TypeInformation
来确定DataSet
的数据类型。
由于logMsgPOJODataSet
DataSet
的类型为LogMessage
,因此Table API不了解其任何子类型。因此,包括LogMessage
的所有字段,但没有子类型字段。
在任何情况下,都无法在同一个表中处理不同类型的行。所有行必须具有相同的架构。处理这种情况的两种方法是:
Map<String, String>
字段。在这两种情况下,转换都需要使用DataSet API完成,例如使用MapFunction
。