Skip to content

Repository query methods

Andreas Kollegger edited this page Sep 29, 2011 · 1 revision

This page acts as pool of ideas and eventually documentation of the way the query method mechanism will work for Spring Data Graph repositories.

Context

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
}

Repository

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

Query building

The query findByGroupNameAndAgeGreaterThan references the property paths group.name and age. findByNameAndGroupNameAndAgeGreaterThanAndGroupMembersAge references name, group.name, age as well as group.members.age.

Start clause

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')

Variable names

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.

Match clause

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)

Where clause

For each referenced property we create a predicate expression (e.g. person.age > ?x according to the keyword and parameter position.

Return clause