【发布时间】:2021-07-17 01:15:56
【问题描述】:
我正在尝试根据条件将字符串拆分为不同的 kafka 主题。
这是拓扑。
- 将字符串拆分为单词。
- 根据条件匹配每个单词(这里是一组好词和一组坏词)
- 如果在字符串中找到至少 1 个来自 Bad words set 的单词,它将被发送到 Bad-string
主题,否则将被发送到好字符串主题。
问题:
每个字符串都只针对一个主题。 (坏字符串主题)
输入:
你们的服务很好。
他又气又伤心。
您的服务很糟糕,但我仍然很高兴。
输出:
好字符串(主题)
你们的服务很好。 (它包含好词,“好”)
错误字符串(主题)
- 他又生气又伤心(里面有不好的词,“生气”和“伤心”)
- 您的服务很糟糕,但我仍然很高兴。 (虽然,有一个 好词“快乐”,但至少有一个坏词“坏”)
代码如下:
@Configuration
@Slf4j
public class SplitSentence {
private static final Set<String> BAD_WORDS = Set.of("angry", "sad", "bad");
private static final Set<String> GOOD_WORDS = Set.of("happy", "good", "helpful");
@SuppressWarnings("unchecked")
@Bean
public KStream<String,String> windowCount(StreamsBuilder builder)
{
var stringSerde = Serdes.String();
var jsonSerde = new JsonSerde<>(CountingDemo.class);
((JsonDeserializer) jsonSerde.deserializer()).setUseTypeHeaders(false);
var input = builder.stream("counting",Consumed.with(stringSerde,jsonSerde));
var feedbackStreams = input.flatMap(splitWords()).branch(isGoodWord(), isBadWord());
boolean newString = feedbackStreams[1].toString().isEmpty();
if(newString)
input.to("good-string");
else
input.to("bad-string");
return input;
}
private Predicate<? super String, ? super String> isBadWord() {
return (key, value) -> BAD_WORDS.contains(value);
}
private Predicate<? super String, ? super String> isGoodWord() {
return (key, value) -> GOOD_WORDS.contains(value);
}
private KeyValueMapper<String, CountingDemo, Iterable<KeyValue<String,String>>> splitWords()
{
return (key,value) -> Arrays
.asList(value.getText().replaceAll("[^a-zA-Z ]", "").toLowerCase().split("\\s+")).stream()
.distinct().map(word -> KeyValue.pair(value.getText(), word)).collect(Collectors.toList());
}
}
CountingDemo.java
public class CountingDemo {
private String name;
private String text;
}
我哪里错了?
有没有更好的逻辑?
【问题讨论】:
-
1) 你期望
feedbackStreams[1].toString()做什么?这永远不是空的。 2) 你如何为此编写一些单元测试而不是在你的主应用逻辑中? -
@OneCricketeer
feedbackStream[1]将包含原始字符串中的坏词。所以我将它转换为字符串,然后检查它是否为空。如果它为空意味着它没有任何坏词意味着原始字符串是一个好字符串。然后它必须转到好的字符串主题。但是如果feedbackStream至少包含 1 个单词,则意味着原始字符串至少有 1 个坏单词,那么原始字符串必须转到 bad-string 主题。 -
实际上
feedbackStream[1]根本不会“包含单词”,因为这只是拓扑的元数据,而不是集合的表示。话虽这么说,你仍然在一个对象的字符串上运行isEmpty,而不是一个列表
标签: java apache-kafka apache-kafka-streams