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