数据集:
user: user_id, nice_id
clicks: click_id, user_id, page_id, time
pages: page_id, page_name
output_clicks: click_id, user_nice_id, page_name, time
用户,点击和页面pcollections都是无限制的。新版本的用户使用新名称,但是他们的nice_id永远不会更改,新版本的页面会带有新的page_names,点击永远不会改变,但是如果点击的page_name发生变化,我们想要一个新的output_click。
因此,page_id上的点击和页面之间有一个CoGroupByKey,其中一个全局窗口触发每个输入元素,并重新发出该页面的每次点击,但如果我有一个类似的全局窗口和共同组 - 在user_id上按键并在每个元素上使用nice_id发出每次点击,然后我们将获得每当用户更改时或每当他们进行新点击时重新发出的用户的所有点击。这将是很多额外的数据。
我想的是在user_id上按键分组之后,在click_id上有一个按键分组,一个新的全局窗口,触发器只触发一次,ParDo本质上是什么都没有,以便逐个键发生,然后重新建立触发每个元素的全局窗口,然后再加入到page_id上的按键组的结果输出。这似乎有用吗?但似乎......有点令人费解。我试图在下面绘制图表。
+-------+ +--------+ +------+
|Pages | | Clicks | | Users|
+---+---+ +---+----+ +--+---+
| | |
+---v----+ +---v----+ +---v----+
|R.Window| |R.Window| |R.Window|
+------+-+ +---------+ ++-------+
| | | |
+----v---v+ +v-----v---+
|CoGroupBy| |CoGroupBy |
|page_id | |user_id |<-- also ParDo that outputs click_id,nice_id mapping
+-------+-+ +------+---+
| |
| +---v----+
| |O.Window|
| +---+----+
| |
| +----v---+
| |GroupBy |
| |click_id|
| +----+---+
| |
| +----v--+
| |nothing|
| |Pardo |
| +---+---+
| |
| +----v---+
| |R.Window|
| +-+------+
| |
+---v------------v+
| CoGroupBy |
| click_id |
+-------+---------+
|
v
Output
R.Window =带有触发器的全局窗口,它会反复触发新数据 O.Window =全局窗口,触发器仅触发一次。
答案 0 :(得分:1)
我认为这不会起作用;通过CoGroupByUserId获取密钥的第一件事就会通过,但所有后续记录都将被删除。
我建议将Flatten和CombinePerKey与自定义CombineFn一起使用,而不是使用CoGroupByKey。 CombineFn将使状态保持在累加器中(确保在Window变换上使用.accumulatingFiredPanes),然后可以选择仅在有新用户名时发出元素。
(旁注:你不需要“没有ParDo”;只需GBK就够了)