我最近开始审查/学习一些有关反应式沙发床的知识,并且我正在尝试使用具有弹簧数据和弹簧靴子的该技术来实现示例,我有以下模型:
@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进行过滤,另一方面,我想检索特定人员的所有地址列表,我的意思是沙发上的文档:
{
"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,而不是简单的对象或列表,所以我不知道该怎么做,有人可以给我一个主意吗?还是有更好的解决方案?
答案 0 :(得分:2)
我找到了一种检索特定人员地址的简便方法,我在查询中指定了要检索的内容:
@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