簡體   English   中英

在Apache Crunch中是否存在將PCollection轉換為PTable的通用方法?

[英]Is there a generic way of converting PCollection to PTable in Apache Crunch?

我在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)));
}

如何實現上述方法的一種通用方法?

有一種更好的方法可以使用PTables util類中的static 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>轉換為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))));

這正是PCollection.by方法的目的,它接受MapFn生成密鑰並返回一個PTable,每個記錄由該MapFn的結果鍵入。

所以你可以這樣做:

PTable<IdDetails, CASegmentsForModification> pTableForCASegments = aggregatedPCollectionForCASegments.by(
    new CASegmentsKeyMapFn(),
    Avros.records(IdDetails.class)
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM