---
title: "22: Graph relations at greater depth | SurrealDB University"
description: "Follow along with interactive SurrealDB lessons featuring hands-on exercises, code examples, and step-by-step instructions."
url: https://surrealdb.com/learn/tour/page-22
---

![Course content preview](https://surrealdb.com/assets/static/town.D95IYf2V.avif)

[Back to Courses](https://surrealdb.com/learn)

Course chapters

[Welcome to the Tour of SurrealDB!](https://surrealdb.com/learn/tour) [1: Connecting to a database](https://surrealdb.com/learn/tour/page-01) [2: Creating records](https://surrealdb.com/learn/tour/page-02) [3: Using the ONLY keyword](https://surrealdb.com/learn/tour/page-03) [4: Non-ASCII record IDs](https://surrealdb.com/learn/tour/page-04) [5: Parentheses, indexing, and accessing fields](https://surrealdb.com/learn/tour/page-05) [6: Deleting records](https://surrealdb.com/learn/tour/page-06) [7: Field order in objects](https://surrealdb.com/learn/tour/page-07) [8: Tips when selecting records](https://surrealdb.com/learn/tour/page-08) [9: Casting and aliases](https://surrealdb.com/learn/tour/page-09) [10: Affixes](https://surrealdb.com/learn/tour/page-10) [11: Updating records](https://surrealdb.com/learn/tour/page-11) [12: Linking records](https://surrealdb.com/learn/tour/page-12) [13: Viewing the database as a whole](https://surrealdb.com/learn/tour/page-13) [14: Schemafull and schemaless](https://surrealdb.com/learn/tour/page-14) [15: Viewing the schema](https://surrealdb.com/learn/tour/page-15) [16: Literal types and assertions](https://surrealdb.com/learn/tour/page-16) [17: INSERT and using JSON](https://surrealdb.com/learn/tour/page-17) [18: FOR loops](https://surrealdb.com/learn/tour/page-18) [19: Basic graph relations](https://surrealdb.com/learn/tour/page-19) [20: Creating graph edges](https://surrealdb.com/learn/tour/page-20) [21: Querying graph relations](https://surrealdb.com/learn/tour/page-21) [22: Graph relations at greater depth](https://surrealdb.com/learn/tour/page-22) [23: Adding and improving data](https://surrealdb.com/learn/tour/page-23) [24: Defining events](https://surrealdb.com/learn/tour/page-24) [25: Defining indexes](https://surrealdb.com/learn/tour/page-25) [26: Improving the schema](https://surrealdb.com/learn/tour/page-26) [27: Visualising graph paths](https://surrealdb.com/learn/tour/page-27) [28: Recursive queries: setup](https://surrealdb.com/learn/tour/page-28) [29: Recursive queries](https://surrealdb.com/learn/tour/page-29) [30: More on recursive queries](https://surrealdb.com/learn/tour/page-30) [31: AI vector search](https://surrealdb.com/learn/tour/page-31) [Done the tour!](https://surrealdb.com/learn/tour/page-32)

# 22: Graph relations at greater depth

Graph queries can go much longer than a single step. If the path `->likes->person` goes from a `person` record to another `person` record, then the path `->likes->person->likes->person` will go one more step down. The result will be the people that are liked by someone that is liked by another.

Here is a quick example of this from the X-Men franchise, in which the character Wolverine likes Jean Grey, who likes the superhero Cyclops. Here, the `hero:wolverine->likes->hero` path leads to Jean Grey, the person he likes, but the `hero:wolverine->likes->hero->likes->hero` path to Cyclops, who he hates! (Well, *sort of* hates. It's complicated.)

```
CREATE hero:wolverine, hero:jean_grey, hero:cyclops;RELATE hero:wolverine->likes->hero:jean_grey;RELATE hero:jean_grey->likes->hero:cyclops;-- returns Jean Grey, whom Wolverine likeshero:wolverine->likes->hero;-- returns Cyclops, whom the person that Wolverine likes likeshero:wolverine->likes->hero->likes->hero;
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

For our `person` records, just repeating `->works_at->place` would make no sense, because libraries don't work at libraries.

Path that makes no sense

```surql
person->works_at->place->works_at->place
```

But the arrows can be turned around at the midpoint to form this path instead.

Path that makes sense

```surql
person->works_at->place<-works_at<-person
```

This path starts at a person and then follows the `->works_at->place` path to see where the person works. Once it reaches the `place`, it then follows the `<-works_at<-` path to see the people that are employed by the library. Finally, it uses `.name` to access their `name` field.

Queries can be written over multiple lines, so breaking these paths down with comments on each line can be helpful when you come back to read your own code later.

```surql
person               -- Start at a person
  ->works_at->place  -- go to the place where the person works
  <-works_at<-person -- then to the people that work at that place
  .name              -- and get their names
```

The end result: all the people that work at a library that the first person works at.

```
SELECT     name,     ->works_at->place    <-works_at<-person.name     AS team_membersFROM person;
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

Response

```surql
[
  {
    name: 'Sara Bellum',
    team_members: [
      'Samm Schwartz',
      'Sara Bellum',
      'Lydia Wyndham'
    ]
  },
  {
    name: 'Lydia Wyndham',
    team_members: [
      'Samm Schwartz',
      'Sara Bellum',
      'Lydia Wyndham'
    ]
  },
  {
    name: 'Samm Schwartz',
    team_members: [
      'Samm Schwartz',
      'Sara Bellum',
      'Lydia Wyndham'
    ]
  }
]
```

Now let's improve the output a bit by having the `team_members` contain every name *except* the name of the current `person`.

Since a graph path returns an array, that lets us use any of SurrealDB's array functions on it. One of them is called [`array::complement()`](https://surrealdb.com/docs/reference/query-language/functions/database-functions/array#arraycomplement) and returns every item in one array minus the items in a second array.

```
array::complement(    ["He", "is", "almost", "always", "on", "time"],    ["always", "almost"]);
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

Response

```surql
[
  'He',
  'is',
  'on',
  'time'
]
```

We can use that at the `->works_at->place<-works_at<-person` path to return every person's name, minus the current person.

```
SELECT     name,   -- The function takes two arrays, so put `name` inside an array    array::complement(->works_at->place<-works_at<-person.name, [name])    AS team_membersFROM person;
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

Now the output shows each person's teammates, without including the person's name as well.

Response

```surql
[
  {
    name: 'Lydia Wyndham',
    team_members: [
      'Sara Bellum',
      'Samm Schwartz'
    ]
  },
  {
    name: 'Sara Bellum',
    team_members: [
      'Lydia Wyndham',
      'Samm Schwartz'
    ]
  },
  {
    name: 'Samm Schwartz',
    team_members: [
      'Lydia Wyndham',
      'Sara Bellum'
    ]
  }
]
```

Previous

21: Querying graph relations

[Previous](https://surrealdb.com/learn/tour/page-21)

Next lesson

23: Adding and improving data

[Next lesson](https://surrealdb.com/learn/tour/page-23)

```json
{"@context":"https://schema.org","@type":"Course","name":"Welcome to the Tour of SurrealDB!","description":"Welcome to the Tour of SurrealDB!","url":"https://surrealdb.com/learn/tour","inLanguage":"en","isAccessibleForFree":true,"provider":{"@type":"Organization","name":"SurrealDB","url":"https://surrealdb.com"},"hasPart":[{"@type":"LearningResource","name":"Welcome to the Tour of SurrealDB!","url":"https://surrealdb.com/learn/tour"},{"@type":"LearningResource","name":"1: Connecting to a database","url":"https://surrealdb.com/learn/tour/page-01"},{"@type":"LearningResource","name":"2: Creating records","url":"https://surrealdb.com/learn/tour/page-02"},{"@type":"LearningResource","name":"3: Using the ONLY keyword","url":"https://surrealdb.com/learn/tour/page-03"},{"@type":"LearningResource","name":"4: Non-ASCII record IDs","url":"https://surrealdb.com/learn/tour/page-04"},{"@type":"LearningResource","name":"5: Parentheses, indexing, and accessing fields","url":"https://surrealdb.com/learn/tour/page-05"},{"@type":"LearningResource","name":"6: Deleting records","url":"https://surrealdb.com/learn/tour/page-06"},{"@type":"LearningResource","name":"7: Field order in objects","url":"https://surrealdb.com/learn/tour/page-07"},{"@type":"LearningResource","name":"8: Tips when selecting records","url":"https://surrealdb.com/learn/tour/page-08"},{"@type":"LearningResource","name":"9: Casting and aliases","url":"https://surrealdb.com/learn/tour/page-09"},{"@type":"LearningResource","name":"10: Affixes","url":"https://surrealdb.com/learn/tour/page-10"},{"@type":"LearningResource","name":"11: Updating records","url":"https://surrealdb.com/learn/tour/page-11"},{"@type":"LearningResource","name":"12: Linking records","url":"https://surrealdb.com/learn/tour/page-12"},{"@type":"LearningResource","name":"13: Viewing the database as a whole","url":"https://surrealdb.com/learn/tour/page-13"},{"@type":"LearningResource","name":"14: Schemafull and schemaless","url":"https://surrealdb.com/learn/tour/page-14"},{"@type":"LearningResource","name":"15: Viewing the schema","url":"https://surrealdb.com/learn/tour/page-15"},{"@type":"LearningResource","name":"16: Literal types and assertions","url":"https://surrealdb.com/learn/tour/page-16"},{"@type":"LearningResource","name":"17: INSERT and using JSON","url":"https://surrealdb.com/learn/tour/page-17"},{"@type":"LearningResource","name":"18: FOR loops","url":"https://surrealdb.com/learn/tour/page-18"},{"@type":"LearningResource","name":"19: Basic graph relations","url":"https://surrealdb.com/learn/tour/page-19"},{"@type":"LearningResource","name":"20: Creating graph edges","url":"https://surrealdb.com/learn/tour/page-20"},{"@type":"LearningResource","name":"21: Querying graph relations","url":"https://surrealdb.com/learn/tour/page-21"},{"@type":"LearningResource","name":"22: Graph relations at greater depth","url":"https://surrealdb.com/learn/tour/page-22"},{"@type":"LearningResource","name":"23: Adding and improving data","url":"https://surrealdb.com/learn/tour/page-23"},{"@type":"LearningResource","name":"24: Defining events","url":"https://surrealdb.com/learn/tour/page-24"},{"@type":"LearningResource","name":"25: Defining indexes","url":"https://surrealdb.com/learn/tour/page-25"},{"@type":"LearningResource","name":"26: Improving the schema","url":"https://surrealdb.com/learn/tour/page-26"},{"@type":"LearningResource","name":"27: Visualising graph paths","url":"https://surrealdb.com/learn/tour/page-27"},{"@type":"LearningResource","name":"28: Recursive queries: setup","url":"https://surrealdb.com/learn/tour/page-28"},{"@type":"LearningResource","name":"29: Recursive queries","url":"https://surrealdb.com/learn/tour/page-29"},{"@type":"LearningResource","name":"30: More on recursive queries","url":"https://surrealdb.com/learn/tour/page-30"},{"@type":"LearningResource","name":"31: AI vector search","url":"https://surrealdb.com/learn/tour/page-31"},{"@type":"LearningResource","name":"Done the tour!","url":"https://surrealdb.com/learn/tour/page-32"}]}
```

```json
{"@context":"https://schema.org","@type":"LearningResource","name":"22: Graph relations at greater depth","description":"Graph relations at greater depth","url":"https://surrealdb.com/learn/tour/page-22","learningResourceType":"lesson","isPartOf":{"@type":"Course","name":"Welcome to the Tour of SurrealDB!","url":"https://surrealdb.com/learn/tour"},"position":23}
```

```json
{"@context":"https://schema.org","@type":"Organization","name":"SurrealDB","url":"https://surrealdb.com","logo":"https://surrealdb.com/assets/static/logo.BG7_TG2b.svg","description":"SurrealDB is the unified data layer for AI. A multi-model database for documents, graphs, vectors, and time-series.","foundingDate":"2022","hasCertification":[{"@type":"Certification","name":"SOC 2 Type 2"},{"@type":"Certification","name":"GDPR"},{"@type":"Certification","name":"Cyber Essentials Plus"},{"@type":"Certification","name":"ISO 27001"}],"owns":[{"@type":"SoftwareApplication","name":"SurrealDB","url":"https://surrealdb.com/surrealdb"},{"@type":"SoftwareApplication","name":"Agent Memory","url":"https://surrealdb.com/agent-memory"}],"knowsAbout":["multi-model databases","document databases","graph databases","vector search","time-series databases","SurrealQL","Agent Memory","real-time databases","embedded databases","context layer","graph ontology","distributed database","knowledge graphs","distributed transaction protocols","highly-scalable databases"],"sameAs":["https://www.wikidata.org/wiki/Q124316308","https://github.com/surrealdb/surrealdb","https://twitter.com/surrealdb","https://www.youtube.com/@surrealdb","https://www.linkedin.com/company/surrealdb","https://discord.gg/surrealdb","https://www.reddit.com/r/surrealdb","https://www.instagram.com/surrealdb","https://medium.com/surrealdb","https://dev.to/surrealdb"]}
```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://surrealdb.com"},{"@type":"ListItem","position":2,"name":"Learn","item":"https://surrealdb.com/learn"},{"@type":"ListItem","position":3,"name":"Page 22","item":"https://surrealdb.com/learn/tour/page-22"}]}
```
