【问题标题】:How Can I do “the same UPDATE-METHOD” updates 02 Collections “at the same time” using Spring Data ReactiveMongoTemplate?如何使用 Spring Data ReactiveMongoTemplate “同时”更新 02 集合?
【发布时间】:2025-12-21 16:05:07
【问题描述】:

1) 问题描述:

  • 我正在使用响应式 Spring-Data + Spring WebFlux + MongoDb + ReactiveMongoTemplate;
  • 我有 02 个集合:TaskProject

2) 我的目标是:

  • 仅使用“一个 更新方法”
  • 更新 02 集合中的 02 文档(同时 - 同时)

3) 代码:

3.1) 采集任务

@Document(collection = "task")
public class Task {

  @Id
  private String _id;

  @Field("pid")
  private String projectId;

  private String taskName;

  private String ownerProject;
}

3.2) 采集项目

@Document(collection = "project")
public class Project {
  @Id
  private String _id;

  private String ownerProject;

  private Task tasksProject;

  private String code;
}

3.3) 我当前的代码 - 不工作

 public Mono<Void> updateWithCriteriaTemplateMult(String id) {

    Query projectDocument = new Query();
    projectDocument.addCriteria(Criteria.where("_id")
                                             .is(id));

    Query taskDocument = new Query();
    taskDocument.addCriteria(Criteria.where("projectId")
                                          .is(id));


    return template
         .update(projectDocument, Project.class)
         .then(template.update(taskDocument, Task.class))
         ;
  }

2) 问题:

  • 如何使用 ReactiveMongoTemplate 编写/执行“相同的 UPDATE-METHOD”“同时”更新两个集合?

    • 示例 01:我的方法需要“更新”两个集合中的“ownerProject”字段:
      • 任务:在本例中,“ownerProject”是一个简单字段
      • 项目:在本例中,“ownerProject”是一个简单字段
  • 示例 02:

    • 我的方法需要在两个集合中“更新”字段“taskName”:
      • 任务:在这种情况下,“任务名称”是一个简单的字段
      • 项目:在这种情况下,“TaskName”是“内部”“tasksProject”字段

非常感谢您的帮助

【问题讨论】:

  • 它是如何“不工作”的?请更新结果、错误等
  • 其实并没有报错信息。简单地说,第二个集合(任务)没有被更新,虽然,第一个(项目)正在更新。好奇怪……
  • 你为什么要链接这么多then
  • @Toerktumlare Opsss。我的错。已更正

标签: java mongodb spring-webflux spring-data-mongodb reactive-mongo-java


【解决方案1】:

更新

这就是我对这个问题的解决方案,使用删除而不是更新(同样的想法):

    public Mono<ProjectChild> DeleteCritTemplMultCollections(
       String projectId,
       String taskId) {

    Query project = Query.query(Criteria.where("_id")
                                        .in(projectId));

    Query taskToDelete = Query.query(Criteria.where("_id")
                                             .in(taskId));

    Update deleteTaskInProjectCollection = new Update();
    deleteTaskInProjectCollection.pull("tasks", taskToDelete);

    Mono<DeleteResult> removeTaskInTaskCollection =
         template.remove(taskToDelete, Task.class);

    return template
         .updateMulti(project, deleteTaskInProjectCollection, "projectchild")
         .then(removeTaskInTaskCollection)
         .then(template.findById(projectId, ProjectChild.class));
  }

为了更好地理解,请关注我的实体:

@Getter
@Setter
@Document(collection = "projectchild")
public class ProjectChild {
  @Id
  private String _id;

  private String name;

  private String code;

  @Field("desc")
  private String description;

  private String startDate;

  private String endDate;

  @Field("cost")
  private long estimatedCost;

  private List<String> countryList;

  private List<Task> tasks;

  @Version
  private Long version;
}


@Getter
@Setter
@Document(collection = "task")
public class Task {

  @Id
  private String _id;

  @Field("pid")
  private String projectId;

  private String name;

  @Field("desc")
  private String description;

  private String ownername;

  private long cost;

  @Version
  private Long version;
}

【讨论】:

    最近更新 更多