---
title: "30: More on recursive queries | 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-30
---

![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)

# 30: More on recursive queries

We saw that you can recursively traverse a record ID in this sort of way.

```surql
place:idiom_tower.{2+collect}.connected_to;
```

Inside the left side of a `SELECT` statement though, the current record ID isn't specified so we need a symbol to refer to it. This is what the `@` symbol is used for.

```
-- @. means "starting from whichever record ID this happens to be"SELECT @.{2+collect}.connected_to FROM place:idiom_tower;
```

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

```surql
[
  {
    connected_to: [
      street:bowler_hat_alley,
      street:rust_row,
      street:schema_boulevard,
      street:index_avenue,
      place:idiom_tower,
      street:transaction_trail,
      place:access_court,
      street:recursive_crossing
    ]
  }
]
```

And to get the same result as the first query, add `VALUE` to remove the key name, and `ONLY` to return a single object instead of an array.

```
-- Both of these have the same outputplace:idiom_tower.{2+collect}.connected_to;SELECT VALUE @.{2+collect}.connected_to FROM ONLY place:idiom_tower;
```

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

## Nested recursive queries

The `@` symbol is also used when you want to put together a nested query that collects the fields of records as it goes. This syntax is a bit interesting so we'll construct it one step at a time.

First is a query that returns the `id` and `name`. As before, you can do this directly from a record ID or via a `SELECT` statement.

```
place:idiom_tower.{ id, name };-- Same output using SELECT:-- SELECT @.{ id, name } FROM ONLY place:idiom_tower;
```

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

Response

```surql
{
  id: place:idiom_tower,
  name: 'Idiom Tower'
}
```

Then add the `connected_to` field to see the connected records.

```
place:idiom_tower.{ id, name, connected_to };-- Same output using SELECT:-- SELECT @.{ id, name, connected_to } FROM ONLY place:idiom_tower;
```

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

Response

```surql
{
  connected_to: [
    street:bowler_hat_alley,
    street:rust_row,
    street:schema_boulevard
  ],
  id: place:idiom_tower,
  name: 'Idiom Tower'
}
```

To include further levels of depth, we'll need to put a number like `{3}` after the record ID. However, this query doesn't work because the database doesn't know which path to choose to recurse.

```surql
place:idiom_tower.{3}.{ id, name, connected_to };
```

To fix it, add `.@` to the path that you want to go down. We'll give this its own alias, `next`.

```
place:idiom_tower.{3}.{ id, name, next: connected_to.@ };-- Same output using SELECT:-- SELECT @.{3}.{ id, name, next: connected_to.@ } FROM ONLY place:idiom_tower;
```

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

The output is a single object that goes down three levels, showing the `id`, `name`, and `next` paths.

Response

```surql
{
  id: place:idiom_tower,
  name: 'Idiom Tower',
  next: [
    {
      id: street:bowler_hat_alley,
      name: 'Bowler Hat Alley',
      next: [
        {
          id: street:index_avenue,
          name: 'Index Avenue',
          next: [
            place:event_junction,
            place:surreal_square,
            place:surrealdb_university,
            street:bowler_hat_alley,
            street:record_link_way,
            street:rust_row,
            street:statement_street
          ]
        },
        {
          id: street:rust_row,
          name: 'Rust Row',
          next: [
            place:idiom_tower,
            street:transaction_trail,
            street:bowler_hat_alley,
            street:index_avenue,
            street:schema_boulevard
          ]
        }
      ]
    },
    {
      id: street:rust_row,
      name: 'Rust Row',
      next: [
        {
          id: place:idiom_tower,
          name: 'Idiom Tower',
          next: [
            street:bowler_hat_alley,
            street:rust_row,
            street:schema_boulevard
          ]
        },
        {
          id: street:transaction_trail,
          name: 'Transaction Trail',
          next: [
            street:rust_row
          ]
        },
        {
          id: street:bowler_hat_alley,
          name: 'Bowler Hat Alley',
          next: [
            street:index_avenue,
            street:rust_row
          ]
        },
        {
          id: street:index_avenue,
          name: 'Index Avenue',
          next: [
            place:event_junction,
            place:surreal_square,
            place:surrealdb_university,
            street:bowler_hat_alley,
            street:record_link_way,
            street:rust_row,
            street:statement_street
          ]
        },
        {
          id: street:schema_boulevard,
          name: 'Schema Boulevard',
          next: [
            place:access_court,
            street:rust_row,
            street:recursive_crossing
          ]
        }
      ]
    },
    {
      id: street:schema_boulevard,
      name: 'Schema Boulevard',
      next: [
        {
          id: place:access_court,
          name: 'Access Court',
          next: [
            street:rust_row,
            street:schema_boulevard
          ]
        },
        {
          id: street:rust_row,
          name: 'Rust Row',
          next: [
            place:idiom_tower,
            street:transaction_trail,
            street:bowler_hat_alley,
            street:index_avenue,
            street:schema_boulevard
          ]
        },
        {
          id: street:recursive_crossing,
          name: 'Recursive Crossing',
          next: street:schema_boulevard
        }
      ]
    }
  ]
}
```

Be sure not to put `{..}` instead of a number as then the query will never end! Or to be precise, it will try to reach the maximum level of depth for recursive queries (256), but the almost endless number of paths will make this impossible to compute.

If you're not sure if a recursive query will go on forever, use a `SELECT` statement instead of working directly from a record because `SELECT` allows you to specify a timeout.

```
SELECT @.{..}.{ id, name, connected_to: connected_to.@ }  FROM ONLY place:idiom_tower  TIMEOUT 1s;
```

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

```surql
'The query was not executed because it exceeded the timeout'
```

Previous

29: Recursive queries

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

Next lesson

31: AI vector search

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

```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":"30: More on recursive queries","description":"More on recursive queries","url":"https://surrealdb.com/learn/tour/page-30","learningResourceType":"lesson","isPartOf":{"@type":"Course","name":"Welcome to the Tour of SurrealDB!","url":"https://surrealdb.com/learn/tour"},"position":31}
```

```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 30","item":"https://surrealdb.com/learn/tour/page-30"}]}
```
