es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo hacer actualizaciones del “mismo método de ACTUALIZACIÓN” en 02 colecciones “al mismo tiempo” utilizando Spring Data ReactiveMongoTemplate?

1) Descripción del problema:

  • Estoy utilizando Reactive Spring-Data + Spring WebFlux + MongoDb + ReactiveMongoTemplate;
  • Tengo 02 Colecciones: Task y Project

2) Mi objetivo es:

  • Usando solo “un método de actualización”
  • que actualice los 02 documentos dentro de las 02 Colecciones (al mismo tiempo – simultáneamente)

3) Código: ###

3.1) Colección Task ####

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

@Id
  private String _id;

@Field("pid")
  private String projectId;

private String taskName;

private String ownerProject;
}

<h4>3.2) Colección Project ####</h4>

<p>“`lang-java
@Document(collection = “project”)
public class Project {
@Id
private String _id;

private String ownerProject;

private Task tasksProject;

private String code;
}




3.3) Mi código actual - que no funciona ####

```lang-java public Mono 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) Pregunta: ###

  • ¿Cómo puedo codificar/hacer que “el mismo método de ACTUALIZACIÓN” actualice ambas Colecciones “al mismo tiempo” utilizando ReactiveMongoTemplate?
    • Ejemplo 01: Mi método necesita “actualizar” el campo “ownerProject” en ambas Colecciones:
    • Task: en este caso ‘ownerProject’ es un campo simple
    • Project: en este caso ‘ownerProject’ es un campo simple
  • Ejemplo 02:
    • Mi método necesita “actualizar” el campo “taskName” en ambas Colecciones:
    • Task: en este caso ‘TaskName’ es un campo simple
    • Project: en este caso ‘TaskName’ es un campo dentro de “tasksProject”

Gracias por cualquier ayuda

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución

    Para actualizar documentos en varias colecciones utilizando un único método de actualización, podemos utilizar la interfaz ReactiveMongoOperations proporcionada por Spring Data MongoDB. Esta interfaz proporciona un método inTransaction() que nos permite ejecutar un conjunto de operaciones en una sola transacción a través de varias colecciones.

    Aquí hay una versión actualizada del método updateWithCriteriaTemplateMult() que actualiza el campo ownerProject en las colecciones Task y Project:

    public Mono<void> updateOwnerProject(String id, String ownerProject) {
        TransactionalOperator transactionalOperator = TransactionalOperator.create(reactiveMongoTransactionManager);
        return transactionalOperator.execute(transactionalOperations -> {
            Mono<updateresult> taskUpdate = reactiveMongoTemplate.updateMulti(
                    Query.query(Criteria.where("projectId").is(id)), 
                    Update.update("ownerProject", ownerProject), 
                    Task.class
            ).all();
            Mono<updateresult> projectUpdate = reactiveMongoTemplate.updateMulti(
                    Query.query(Criteria.where("_id").is(id)), 
                    Update.update("ownerProject", ownerProject), 
                    Project.class
            ).all();
            return Mono.zip(taskUpdate, projectUpdate);
        }).then();
    }
    
    • Creamos un TransactionalOperator utilizando el reactiveMongoTransactionManager, el cual debe ser configurado antes de poder llamar a este método.
    • Luego, ejecutamos un conjunto de operaciones utilizando el método transactionalOperator.execute().
    • Dentro de esta transacción, ejecutamos dos operaciones de actualización utilizando el método reactiveMongoTemplate.updateMulti() para actualizar el campo ownerProject en las colecciones Task y Project.
    • Utilizamos el método all() para recopilar todos los resultados de las actualizaciones en el Mono.
    • Finalmente, utilizamos Mono.zip() para combinar dos Monos en un solo Mono.

    Para actualizar el campo anidado taskName en las colecciones Task y Project, podemos utilizar el siguiente método:

    public Mono<void> updateTaskName(String id, String taskName) {
        TransactionalOperator transactionalOperator = TransactionalOperator.create(reactiveMongoTransactionManager);
        return transactionalOperator.execute(transactionalOperations -> {
            Mono<updateresult> taskUpdate = reactiveMongoTemplate.updateMulti(
                    Query.query(Criteria.where("projectId").is(id)), 
                    Update.update("taskName", taskName), 
                    Task.class
            ).all();
            Mono<updateresult> projectUpdate = reactiveMongoTemplate.updateMulti(
                    Query.query(Criteria.where("_id").is(id)), 
                    Update.update("tasksProject.taskName", taskName), 
                    Project.class
            ).all();
            return Mono.zip(taskUpdate, projectUpdate);
        }).then();
    }
    
    • Nuevamente utilizamos reactiveMongoTemplate.updateMulti() para actualizar el campo taskName en las colecciones Task y Project.
    • Para la colección Task, utilizamos Update.update("taskName", taskName).
    • Para la colección Project, utilizamos Update.update("tasksProject.taskName", taskName) para actualizar el campo anidado taskName dentro de Task.
    • Nuevamente utilizamos Mono.zip() para combinar dos Monos en un solo Mono.

    Nota: En ambos métodos, estamos utilizando el reactiveMongoTransactionManager, el cual debe ser configurado en nuestro contexto de aplicación. Podemos configurarlo de la siguiente manera:

    @Bean
    public ReactiveMongoTransactionManager reactiveMongoTransactionManager(ReactiveMongoDatabaseFactory dbFactory) {
        return new ReactiveMongoTransactionManager(dbFactory);
    }
    

    Esto configura un bean ReactiveMongoTransactionManager que se puede utilizar para crear un TransactionalOperator en nuestros métodos de actualización.

    ¡Espero que esto ayude! Avísame si tienes alguna otra pregunta.

Comments are closed.