在reactor mono中获取Map的和

mnemlml8  于 2021-07-08  发布在  Java
关注(0)|答案(2)|浏览(464)

如何将mono/flux的所有结果相加
我有一些React式代码,其中我返回一个通量并链接一些其他函数,我将用一些代码来解释它。

return commentService.getAllCommentByIssueId(issueId)
                .map {
                    taggingService.tagging(it.content).map {
                        //Get the count of the returned set and add it up to 
                        //all the other returned map results
                        //So the result should be like
                        //tags in first comment 2, tags in second comment 3
                        //so it should return 5
                    }

所以我返回一个流量,这是一个流量的评论。我想把这个查询的所有注解Map到一个函数,在这个函数中,我扫描每个注解的内容以查找标记,这是由 taggingservice.tagging ,该函数返回 Mono<MutableSet<UUID>> 所以它返回所有被标记的uuid。一个问题有x个评论,我想总结所有评论中的所有标签。
我想做的是统计问题的每个评论的所有标签,并在statsmodel中返回它,statsmodel由 StatsModel(issueId,numberOfTagsInComments) 现在我将向您展示标记功能:
(我测试了功能,它正在工作)

fun tagging(text:String) : Mono<MutableSet<UUID>> {
        val words = text.split( " ")
                .filter { it.startsWith("@")}
        val matches : MutableSet<UUID> = mutableSetOf()

        return userRepository.findAll().collectList()
                .map { userList ->
                    for(word in words){
                        userList.map {user ->
                            if(user.username == word.substring(1)) {
                                matches.add(user.id!!)
                            }
                        }
                    }
                    matches
                }
    }

还有我的评论库,我正在使用这个repo的第一个函数。

@Repository
interface CommentRepository: ReactiveCrudRepository<CommentModel, UUID> {
    fun findAllByIssueId(issueId: UUID): Flux<CommentModel>
    fun findAllByUserId(userId: UUID): Flux<CommentModel>
}
rqcrx0a6

rqcrx0a61#

你的问题不清楚,但就像我说的,似乎你想减少。
你的问题不清楚,因为你正在返回一个 Set 从你的标签功能,但一个 Set 只允许唯一的值,所以如果同一个标记在注解中出现两次呢?
无论如何,假设您想要每个注解中唯一标记的总数,您可以考虑:
我制作了一个标签和uuid的db(map)

Map<String, UUID> tags;
tags = Arrays.asList(new String[] {"tag1", "tag2"}).stream().collect(Collectors.toMap(Function.identity(), s->UUID.randomUUID() ));

标记函数的我的版本:

Mono<Set<UUID>> tagging(String string) {
    return Flux.fromArray(text.split(" ")).filter(str->str.startsWith("@")).map(str->str.substring(1)).map(tags::get).collect(Collectors.toSet());
}

获取数据的函数 Flux<String> 评论:

Flux<String> getAllComments() {
    return Flux.fromArray(new String[] {"this is @tag1", "and @tag2", "finally @tag1 and @tag2", "unclear @tag1 and @tag1"});
}

以及一些简单的逻辑来计算每个 Set :

getAllComments()
    .flatMap(this::tagging)
    .map(Set::size)
    .reduce(Integer::sum)
    .map(StatsModel::new)
    .subscribe(System.out::println);

假设 lombok 他是你的朋友

@ToString
@RequiredArgsConstructor
class StatsModel{
    UUID issueId = UUID.randomUUID();
    @NonNull
    Integer count;
}

给了我:

StatsModel(issueId=a3cf1243-8a89-406c-b0e8-c13a6bdc832c, count=5)

生成的uuid是免费的。

pzfprimi

pzfprimi2#

让我们把最终目标说清楚:你想得到 StatsModel(issueId, numberOfUniqueTagsInComments) . 然后我们可以将其分解为子问题(为了清晰起见,我将更改一下命名方式):
获取问题的所有评论: fun getAllComments(issueId): Flux<Comment> 从内容中获取唯一标记: fun uniqueTags(text: String): Mono<Set<UUID>> 合并标记:给出 List<Set<UUID>> ,您可以使用 reduce 去参加决赛 Set<UUID> . 注意,对于这个你不需要使用reactor,只需要使用普通kotlin。
综合起来:

getAllComments(issueId)            // Flux<Comment>
  .flatMap { uniqueTags(it) }      // Flux<Set<UUID>>
  .collectList()                   // Mono<List<Set<UUID>>
  .map { uuidSets ->
    uuidSets
      .reduce { acc, set -> acc + set } // Set<UUID>
      .size()                           // Int
  }
  .map { StatsModel(issueId, it) }

相关问题