-
Notifications
You must be signed in to change notification settings - Fork 0
Repository query methods
This page acts as pool of ideas and eventually documentation of the way the query method mechanism will work for Spring Data Graph repositories.
class Person {
@Indexed
private String name;
private String age;
@RelatedTo(type="members",direction=INCOMING)
private Group group;
// Getters and setters here
}
class Group {
@Indexed
private String name;
@RelatedTo(type = "members", direction = Direction.OUTGOING)
private Set<Person> members;
// Getters and setters here
}public interface PersonRepository extends NodeRepository<Person, Long> {
// @Query("start group=(group,name,?0)
// match person<-[:members]-group
// where person.age > ?1 return person)")
Iterable<Person> findByGroupNameAndAgeGreaterThan(String name, int age);
// @Query("start person=(person,name,?0), group=(group,name,?1)
// match person<-[:members]-group,
// group-[:members]->groupMembers
// where person.age > ?2 and groupMembers.age = ?3")
Iterable<Person> findByNameAndGroupNameAndAgeGreaterThanAndGroupMembersAge(
String personName, String name, int age, int memberAge);
}The query findByGroupNameAndAgeGreaterThan references the property paths group.name and age. findByNameAndGroupNameAndAgeGreaterThanAndGroupMembersAge references name, group.name, age as well as group.members.age.
By default we can create a start expression to all nodes of the domain type the repository manages (Person in this case: start person=(__types__,className,'com.acme.Person') (more general start $domainClass.toLower()=(__types__,className,'$domainClass.FQN')). If the where-clause references an indexed property we can narrow the start nodes to those matching this property. In our case we refer to Person.group.name which is indexed, so we can initialize that variable as start nodes start person_group = (Group,name,'x')
Potential graph variables names are derived from the path to (including the) root except the last property. So for instance group.name will become person_group and colleagues.group.name will become person_colleagues_group. Paths of root entity properties will just be the root entity type, e.g. name will become `person.
For each referenced relationship we create the appropriate match expression. So we inspect the @Related annotation and build person<-[:members]-group from it considering property type, owning type as well as relation direction.
class OwningType {
@RelatedTo(type, direction)
PropertyType relationship;
}- Direction.INCOMING -
($owningType)<-[:$type]-($relationship) - Direction.OUTGOING -
($owningType)-[:$type]->($relationship) - Direction.BOTH -
($owningType)-[:$type]-($relationship)
For each referenced property we create a predicate expression (e.g. person.age > ?x according to the keyword and parameter position.