Neo4j and GraphQL Heavenly Match #1 - Directional Relationships

muddybootscode

Michael Porter

Posted on January 5, 2020

Neo4j and GraphQL Heavenly Match #1 - Directional Relationships

Easily one of the most useful features of the GRANDstack's integration with GraphQL is the ability to create and express directional relationships between nodes in your graph, or entities in your data. A simple example would be two friends, which you could express in your GraphQL Schema like:

type Person {
  name: String
  friends: [Person] @relation(name: "FRIEND", direction: "OUT)
}
Enter fullscreen mode Exit fullscreen mode

You can easily expand on this simple schema and add any amount of relationships that you desire like; favorite restaurants, hangouts, workplaces, family, etc. In addition if you want to place properties on the relationship you can do that as well by making the relationship itself a type in your schema, lets say you want to track a persons work history:

type Workplace {
  name: String
  address: String
  pastEmployees: [Person] @relation(name: "WORKED_AT", direction: "IN")
  currentEmployees: [Person] @relation(name: "WORKS_AT", direction: "IN")
}

type WorkedAt @relation(name: "WORKED_AT"){
   startDate: Date
   endDate: Date
   startSalary: Float
   endSalary: Float
}
Enter fullscreen mode Exit fullscreen mode

You then expand your Person type:

type Person {
  name: String
  worksAt: WorkPlace @ relation(name: "WORKS_AT", direction: "OUT")
  workedAt: [WorkPlace] @relation(name: "WORKED_AT", direction: "OUT")
}
Enter fullscreen mode Exit fullscreen mode

This gives you the ability to easily create a complete history of work for your Person and allows you to track current and past employees of your Workplace. The connections between the two then provide you the ability to dig deep into the history of both. What if you wanted to know the life time average ending salary for your person? Because you're using the GRANDstack you have access to Cypher directives via Neo4j:

type Person {
  name: String
  worksAt: WorkPlace @ relation(name: "WORKS_AT", direction: "OUT")
  workedAt: [WorkPlace] @relation(name: "WORKED_AT", direction: "OUT")
  avgEndingSalary: Float @cypher (
     statement: "MATCH (this)-[r:WORKED_AT]->(:WorkPlace) return avg(r.endSalary)
}
Enter fullscreen mode Exit fullscreen mode

You can see how this ability to query relationships and the properties on them allows you to add a wealth of depth and detail to your application. You don't have to stop there, with the dates provided you can track avg time spent at each job or get the exact amount of days a person worked somewhere, the number of details you can now extract from this data only grows. The directional nature of the relationships set also allow you to control the flow of information and you can begin to use Graph Algorithms to make sense of your data. Want to find the shortest path between two companies via past or present employees? There's a Graph Algorithm for that! Want to find a person who can act as a bridge between two companies? There's a Graph Algorithm for that too! Being able to create and track these numerous relationships and their properties is just one of the reasons that GraphQL and Neo4j with the GRANDstack are a match made in heaven.

  • note: This is a simple use case and would not be optimized for very large data set queries. A heavenly Match
💖 💪 🙅 🚩
muddybootscode
Michael Porter

Posted on January 5, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related