-
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.