如何获得具有反应性基础的对象的嵌套列表?

问题描述 投票:2回答:1

我最近开始回顾/学习一些关于反应性沙发基础的内容,我正在尝试使用弹簧数据和弹簧启动技术实现样本,我有以下模型:

@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());
    }
}

到目前为止这很好用,我可以检索所有的人,也可以通过特定人的id过滤,另一方面我想检索特定人的所有地址列表,我的意思是我在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而不是简单的对象或List,所以我不知道该怎么做,有人可以给我一个想法吗?还是有更好的解决方案?

spring-boot spring-data reactive-programming couchbase
1个回答
2
投票

我找到了一种简单的方法来检索特定Person的地址,我使用了一个查询,我指定了要检索的内容:

@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 _IDMETA(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

© www.soinside.com 2019 - 2024. All rights reserved.