首页 > 解决方案 > Spring reactive - 更新列表中的嵌套对象,然后保存父对象

问题描述

我有一个根对象,它有一个嵌套的对象列表。我需要访问该对象的嵌套列表,对它们执行一些操作,然后将结果保存回去。

我似乎让自己绊倒了 nested flatMaps

我设法想出的最好的是:

public Flux<Face> scanSingleVideo(@PathVariable final String id) {

    // Reactive MongoDB Find by ID
    return videoRepository.findById(id)

            // A single video is returned, the video has an ArrayList of thumbnails
            .flatMapMany(video -> Flux.fromIterable(video.getThumbnails()))

            // Each thumbnail has a 'path' value which is just a string
            .map(Thumbnail::getPath)

            // Passing the path into a function which does some business work. The function returns a Flux of faces
            .flatMap(faceService::detectFaces);

            // Q: How can I get these new objects into an array on the Thumbnail, then save the video object with the updated thumbnail? 
}

但是,如果这甚至是正确的方向,我现在就被困住了。对于上下文,这是我正在使用的两个域

视频对象

public class Video {
    // {..}
    List<Thumbnail> thumbnails = new ArrayList<>();
}

缩略图对象

public class Thumbnail {
    // {..}
    String path;

    Set<Face> faces = new HashSet<>();
}

第一次尝试在 . 上设置新对象时我感觉很接近Thumbnail,但是非常难看,感觉好像我在某个地方出错或错过了我可以使用的关键方法。然而,这确实有效。

public Mono<Video> scanSingleVideo(@PathVariable final String id) {
    return videoRepository.findById(id)
            .flatMap(video -> {
                video.getThumbnails().forEach(thumbnail -> faceService
                        .detectFaces(thumbnail.getPath())
                        .flatMap(face -> {
                            thumbnail.getFaces().add(face);

                            return Mono.just(thumbnail);
                        }).flatMap(t -> {
                            video.getThumbnails().add(t);

                            return videoRepository.save(video);
                        }).subscribe());

                return videoRepository.save(video);
            });
}

我不喜欢嵌套订阅,但我不确定如何处理这个问题。


编辑:对于遇到此问题的任何人,您可以稍微清理我的“工作”尝试,但我仍然认为它不正确。

public Mono<Video> scanSingleVideo(@PathVariable final String id) {
    return videoRepository.findById(id)
            .flatMap(video -> {
                video.getThumbnails().forEach(thumbnail -> faceService
                        .detectFaces(thumbnail.getPath())
                        .flatMap(face -> getPublisher(video, thumbnail, face))
                        .distinct()
                        .subscribe());

                return videoRepository.save(video);
            });
}

private Publisher<? extends Video> getPublisher(Video video, Thumbnail thumbnail, Face face) {
    thumbnail.getFaces().add(face);
    video.getThumbnails().add(thumbnail);

    return videoRepository.save(video);
}

标签: javaspring-bootreactive-programming

解决方案


推荐阅读