我在util类中有这些方法,它们将特定的PCollection转换为特定的PTable。
public static PTable<IdDetails, CASegmentsForModification> getPTableForCASegments(PCollection<CASegmentsForModification> aggregatedPCollectionForCASegments) {
return aggregatedPCollectionForCASegments.parallelDo(new CASegmentsPTableConverter(),
Avros.tableOf(Avros.records(IdDetails.class), Avros.records(CASegmentsForModification.class)));
}
public static PTable<IdDetails, UserPrimaryIdMapping> getPTableForPrimaryIdMapping(PCollection<UserPrimaryIdMapping> pCollectionOfUserPrimaryIdMapping) {
return pCollectionOfUserPrimaryIdMapping.parallelDo(new UserPrimaryIdMappingPTableConverter(),
Avros.tableOf(Avros.records(IdDetails.class), Avros.records(UserPrimaryIdMapping.class)));
}
public static PTable<IdDetails, UserGroupSegments> getPTableForUserGroupSegments(PCollection<UserGroupSegments> pCollectionOfUserGroupSegments) {
return pCollectionOfUserGroupSegments.parallelDo(new UserGroupSegmentsPTableConverter(),
Avros.tableOf(Avros.records(IdDetails.class), Avros.records(UserGroupSegments.class)));
}
如何实现上述方法的一种通用方法?
答案 0 :(得分:2)
有一种更好的方法可以使用PTables util类中的静态asPtable方法。您的PCollection必须是Pair类型,PTable结果将是PTable类型
public static <K,V> PTable<K,V> asPTable(PCollection<Pair<K,V>> pcollect)
根据您的示例,您只需创建DoFn(或扩展类)即可返回Avros.pairs(Avros.records(yourClass.class),Avros.records(yourOtherClass.class))。
另一种方法是使用预定义的MapFn ExtractKEyFn并将其应用于您的集合。您需要实现map方法来提取密钥并生成密钥值输出。它基本上是相同的想法,之后你可以转换PCollection&gt;进入PTable
它应该为您节省大量的样板代码。
以防万一,还有其他功能可能有用FilterFn,但是当您使用MemPipeline进行单元测试时,我们发现了一些错误。我建议的第一种方法应该是最安全的。
编辑:
保存一些代码的良好平衡是使用字段名称根据字段名称获取密钥,并为每个PCollection调用此MapFn。
//we are assuming the key will be in the first level of your record
public class GenericRecordToPair <V extends GenericRecord, K extends GenericRecord> extends MapFn<V, Pair<K, V>> {
String key;
public GenericRecordToPair(String key){
this.key = key;
}
@Override
public Pair<T, TupleN> map(S input) {
return new Pair<K,V> (input.get(key), input);
}
}
从您的示例中,您可以执行类似
的操作PCollection<UserGroupSegments> pCollectionOfUserGroupSegments = ...//comming from somewhere
PCollection<UserPrimaryIdMapping> pCollectionOfUserPrimaryIdMapping = ...//comming from somewhere
PTable<IdDetails, UserGroupSegments> pTable1 = PTables.asPTable(pCollectionOfUserGroupSegments.parallelDo(new GenericRecordToPair("idDetails"), Avros.pairs(Avros.records(IdDetails.class), Avros.records(UserGroupSegments))));
PTable<IdDetails, UserPrimaryIdMapping> pTable2 = PTables.asPTable(pCollectionOfUserPrimaryIdMapping.parallelDo(new GenericRecordToPair("idDetails"), Avros.pairs(Avros.records(IdDetails.class), Avros.records(UserPrimaryIdMapping))));
答案 1 :(得分:0)
这正是PCollection.by
方法的目的,它接受MapFn生成密钥并返回一个PTable,每个记录由该MapFn的结果键入。
所以你可以这样做:
PTable<IdDetails, CASegmentsForModification> pTableForCASegments = aggregatedPCollectionForCASegments.by(
new CASegmentsKeyMapFn(),
Avros.records(IdDetails.class)
)