如何发现和过滤Kafka Streams中的重复记录

时间:2018-09-26 21:53:02

标签: apache-kafka apache-kafka-streams

假设您有一个带有空键的主题,值是

{id:1, name:Chris, age:99}

让我们说您想按人数计算人数。您将执行以下操作:

nameStream.groupBy((key,value) -> value.getName())
           .count();

现在让我们说它是有效的,您可以获得重复的记录,并且可以根据ID判断它是重复的。

例如:

{id:1, name:Chris, age:99}
{id:1, name:Chris, age:xx}

应计数为1和

   {id:1, name:Chris, age:99}
   {id:2, name:Chris, age:xx}

应计数为2。

您将如何实现?我以为reduce会起作用,但是却误解了它的作用。

1 个答案:

答案 0 :(得分:3)

您可以使用多个属性进行分组。通过串联创建自定义密钥并作为密钥传递:

KTable<String,String> modifiedTable =  nameStream.groupBy((key,value) -> value.getName()+value.getId()).reduce((aggVal,newval) -> aggVal);

KTable上方将为具有给定名称和ID的任何记录提供更新状态。 因此,对于{id:1,name:Chris.....},它在KTable中只有一条记录:

在以下情况下,两个记录都将存在:

<Chris1,  {id:1, name:Chris, age:99}> 
<Chris2,   {id:2, name:Chris, age:xx}> 

现在您要使用name属性进行计数操作。因此,将键更改为 name 并重新分组表并执行count()。

KTable countTable = modifiedTable.groupBy((k,v)-> KeyValue.pair(v.getName(), v)).count();

此处count()将在KTable的顶部执行。 KTable是任何给定ID的更新视图。
因此,对于以下输入,modifiedTable一次将有1条记录作为键“ Chris1”的更新值,您将获得 count => 1

<Chris,1> // Here key will be Chris1

以下输入将导致** count => 2

{id:1, name:Chris, age:99}  // Here key was be Chris1
{id:2, name:Chris, age:xx}  // Here key was be Chris2