This is the query in the repository which works fine.
public interface PlayerRepo extends CrudRepository<Player, String>{
@Query("#{#n1ql.selectEntity} WHERE code = $1 and #{#n1ql.filter}")
public List<Player> findPlayersWithCode(String code);
}
I want to fetch specific field from Player document, like this:
@Query("#{#n1ql.selectEntity.name} WHERE code = $1 and #{#n1ql.filter}")
public List<String> findPlayerNamesWithCode(String code);
Is it possible to do this, I am using spring-data-couchbase 2.1.2
Currently, this is not possible from a repository. Spring Data Hopper introduced a Projection
feature that would allow it, but the Couchbase store implementation doesn't yet cover it.
There's something close in the CouchbaseTemplate
, which has a findByN1QLProjection
method, but it needs a DTO dedicated to the query. For example:
SELECT name, lastName FROM #{#n1ql.bucket} WHERE code = $1 AND #{#n1ql.filter}
which is equivalent (in pure N1QL) to:
SELECT name, lastName FROM bucketThatBacksRepository WHERE code = $1 AND _class = "com.example.Person"
would require the following class to work with findByN1QLProjection
:
public class PersonNameDTO {
private final String name;
private final String lastName;
//constructor and maybe getters/setters needed but omitted here
}
And it would produce a List<PersonNameDTO>
. Note that this is not hugely different from the projection feature I was talking about, except it's designed around interfaces rather than concrete DTO classes.
Note that you shouldn't use the #{#n1ql.selectEntity}
SpEL since its purpose is to have a large SELECT clause that covers all the fields of a given entity (whereas here you want to restrict the SELECT clause).
It also covers the FROM part with the correct bucket associated to your repository, but the #{#n1ql.bucket}
also covers that part (and that part only)...