Как я могу получить вложенный список объектов с активной реактивной базой? - PullRequest
0 голосов
/ 26 августа 2018

Недавно я начал изучать / изучать некоторые сведения о реактивной базе, и я пытаюсь реализовать образец с использованием этой технологии с использованием данных пружины и загрузки пружины. У меня есть следующие модели:

@Document
public class Person {
    @Id
    private String id;
    @Field
    private String name;
    @Field
    private String lastName;
    @Field
    private List<Address> address;
    // Getters & Setters
}

@Document
public class Address {
    @Id
    private String code;
    @Field
    private String mainStreet;
    @Field
    private String secondStreet;
    // Getters & Setters
}

Репозитории:

@N1qlPrimaryIndexed
@ViewIndexed(designDoc = "address")
public interface AddressRepository extends ReactiveCouchbaseRepository<Address, String> {
}

@N1qlPrimaryIndexed
@ViewIndexed(designDoc = "person")
public interface PersonRepository extends ReactiveCouchbaseRepository<Person, String> {
}

Служба:

public interface PersonService {
    Flux<Person> getAllPersons();
    Mono<Person> getPerson(String id);
    Flux<Address> getAddressesByPerson(String id);
}

@Service
public class PersonServiceImpl implements PersonService {
    @Autowired
    private PersonRepository personRepository;

    @Override
    public Flux<Person> getAllPersons() {
        return personRepository.findAll();
    }

    @Override
    public Mono<Person> getPerson(String id) {
        return personRepository.findById(id);
    }

    @Override
    public Flux<Address> getAddressesByPerson(String id) {
        return null;
    }
}

Контроллер:

@RestController
@RequestMapping("/sample_couchbase")
public class PersonController {
    @Autowired
    private PersonService personService;

    @GetMapping("/people")
    public Flux<Person> getAllPersons() {
        return personService.getAllPersons();
    }

    @GetMapping("/person/{id}")
    public Mono<ResponseEntity<Person>> getPersonsById(@PathVariable String id) {
        return personService.getPerson(id)
                            .map(person -> ResponseEntity.status(HttpStatus.OK).body(person))
                            .defaultIfEmpty(ResponseEntity.notFound().build());
    }
}

Как такПока это работает хорошо, я могу получить всех людей, а также отфильтровать по идентификатору конкретного человека, с другой стороны, я хотел бы получить весь список адресов конкретного человека, я имею в виду этот документ в couchbase:

{
  "id": "1",
  "name": "Scooby",
  "lastName": "Doo",
  "address": [
    {
      "code": "A1",
      "mainStreet": "AAA",
      "secondStreet": "BBB",
      "phone": "11111",
      "place": "home"
    },
    {
      "code": "A2",
      "mainStreet": "CCC",
      "secondStreet": "DDD",
      "phone": "22222",
      "place": "work"
    },
    {
      "code": "A3",
      "mainStreet": "EEE",
      "secondStreet": "FFF",
      "phone": "33333",
      "place": "treasury"
    }
  ],
  "classType": "com.jcalvopinam.model.Person"
}

Когда я звоню в службу, например: http://localhost:8080/sample_couchbase/person/1/addresses Я хочу получить это:

"address": [
    {
      "code": "A1",
      "mainStreet": "AAA",
      "secondStreet": "BBB",
      "phone": "11111",
      "place": "home"
    },
    {
      "code": "A2",
      "mainStreet": "CCC",
      "secondStreet": "DDD",
      "phone": "22222",
      "place": "work"
    },
    {
      "code": "A3",
      "mainStreet": "EEE",
      "secondStreet": "FFF",
      "phone": "33333",
      "place": "treasury"
    }
  ]

Я представлял, как создать в хранилище метод примерно так:

Mono<Person> findById(String id);

А на уровне сервиса я представляю себе получение всего объекта и затем фильтрацию по адресу, но это нечто отличное от того, что я привык делать, теперь я использую Mono и Flux, а не простой объект илиСписок, так что я не знаю, как это сделать,кто-нибудь может дать мне идею?или есть лучшее решение?

1 Ответ

0 голосов
/ 02 сентября 2018

Я нашел простой способ получить адреса определенного человека, я использовал запрос, в котором я указал, что я хочу получить:

@Query("SELECT addresses, META(sample).id as _ID, META(sample).cas as _CAS FROM `sample` WHERE id = $1")
Flux<Person> findAddressesByPerson(String id);

Я заметил, что необходимо указать META(sample).id as _ID и META(sample).cas as _CAS атрибуты, чтобы избежать следующей ошибки:

org.springframework.data.couchbase.core.CouchbaseQueryExecutionException: Unable to retrieve enough metadata for N1QL to entity mapping, have you selected _ID and _CAS?; nested exception is rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: com.couchbase.client.java.query.DefaultAsyncN1qlQueryRow.class

Если вы хотите взглянуть на реализацию более подробно, вот пример: https://github.com/juanca87/sample-couchbase-rx

...