Google cloud dataflow 如何使用数据流计算每个键的顶部唯一值结果?

Google cloud dataflow 如何使用数据流计算每个键的顶部唯一值结果?,google-cloud-dataflow,Google Cloud Dataflow,我对Dataflow及其编程模型相对较陌生,正在努力解决一个需要计算客户最高消费前10周的问题。如果这是一个愚蠢的问题,我道歉 我拥有的数据包括我用作密钥的客户ID和几百万条包含时间戳和花费值的记录 我创建了一个类似这样的提取方法(不包括日志记录和日期格式化程序)。它接收一个BigQuery表行,我从中提取客户ID、花费和时间戳,并从中获取周数: static class ExtractSpend extends DoFn<TableRow, KV<String, SpendByWe

我对Dataflow及其编程模型相对较陌生,正在努力解决一个需要计算客户最高消费前10周的问题。如果这是一个愚蠢的问题,我道歉

我拥有的数据包括我用作密钥的客户ID和几百万条包含时间戳和花费值的记录

我创建了一个类似这样的提取方法(不包括日志记录和日期格式化程序)。它接收一个BigQuery表行,我从中提取客户ID、花费和时间戳,并从中获取周数:

static class ExtractSpend extends DoFn<TableRow, KV<String, SpendByWeek>> {
    private static final long serialVersionUID = 0;

    @Override
    public void processElement(ProcessContext c) {
        String custId = (String) row.get("customerID");
        LocalDateTime date = LocalDateTime.parse((String) row.get("timestamp"), dateTimeFormatter);

        WeekFields weekFields = WeekFields.of(Locale.getDefault());
        int weekNumber = date.get(weekFields.weekOfWeekBasedYear());

        Double spend = (Double) row.get("spend");

        SpendByWeek spendByWeek = new SpendByWeek(weekNumber, spend.doubleValue());
        c.output(KV.of(custId, spendByWeek));

   }
}
静态类扩展DoFn{
私有静态最终长serialVersionUID=0;
@凌驾
公共void processElement(ProcessContext c){
String custId=(String)row.get(“customerID”);
LocalDateTime日期=LocalDateTime.parse((字符串)row.get(“时间戳”),dateTimeFormatter);
WeekFields WeekFields=WeekFields.of(Locale.getDefault());
int weekNumber=date.get(weekFields.weekFoekBaseDyear());
双倍支出=(双倍)行。获取(“支出”);
SpendByWeek SpendByWeek=新的SpendByWeek(周数,spend.doubleValue());
c、 输出(千伏(客户,每周支出));
}
}
但我不知道如何获取此输出并将其分组,这样我就可以添加每个客户ID和每周的支出值,对它们进行排序,并输出每个客户的
PCollection
及其前10个每周支出值


有谁能帮我解决这个问题吗?

如果你只想通过分组来实现这一点,你需要首先按客户ID和周分组来计算
总和,然后将周移到值中,并仅按客户ID重新分组以计算
顶部。您也可以使用窗口来完成这项操作,而不是将周放在键中。请参见结尾,了解有关执行此操作的一些详细信息

完成此操作后,您将有一个
PCollection
,其中给定密钥每周发生一次。通过定义实现可序列化的比较器
并将其与
top.perKey()
一起使用,可以确定每个给定用户id的前
SpendByWeek


使用Windows计算每个用户每周的花费

正如上面提到的,您可以使用窗口来帮助计算每周的花费

  • 编写一个类似于ExtractExpense的DoFn,它获取一个TableRow并输出一个KV,KV是由客户ID键入的单独支出行,并使用
    outputWithTimestamp
    输出输出
  • 然后应用一个窗口转换,例如
    FixedWindows
    ,它将把事件划分为指定大小的窗口。在您的情况下,您可能需要
    FixedWindows.of(Duration.standardWeeks(1))
    CalendarWindows.weeks(…)
  • 然后应用一个变换,例如
    Sum.doublesPerKey()
  • 此时,您将有一个
    PCollection
    ,其中包含一个每周窗口
    KV
    ,其中每个条目都是该钥匙在一周内的总花费

  • 然后,您可以运行一个
    DoFn
    ,以获取每小时的窗口并将该信息移动到值中(因此现在您有了
    KV
  • 将Window.into应用于切换到
    GlobalWindows
  • 然后应用
    Top.perKey
    操作,如上所述

  • 嗨,Darren,你有没有研究过中的求和和和顶变换?谢谢Ben,这非常有效。非常感谢。