У меня есть корневой объект, у которого есть вложенный список объектов.Мне нужно получить доступ к этому вложенному списку объектов, предварительно выполнить некоторые действия с ними и затем сохранить результаты обратно.
Кажется, я запутался во вложенном 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);
}