---
title: "Reading data | SurrealDB University"
description: "Reading data. A chapter of SurrealDB Fundamentals, a hands-on course with runnable examples."
url: https://surrealdb.com/learn/fundamentals/schemaless/reading-data
---

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

Course chapters

[SurrealDB Fundamentals](https://surrealdb.com/learn/fundamentals) [Introduction](https://surrealdb.com/learn/fundamentals) [Welcome to SurrealDB University](https://surrealdb.com/learn/fundamentals/intro/welcome) [Intro to SurrealDB](https://surrealdb.com/learn/fundamentals/intro/surrealdb) [Why SurrealQL is SQL-like](https://surrealdb.com/learn/fundamentals/intro/surrealql) [Part 1: Schemaless CRUD](https://surrealdb.com/learn/fundamentals/schemaless) [Introduction](https://surrealdb.com/learn/fundamentals/schemaless) [Record IDs](https://surrealdb.com/learn/fundamentals/schemaless/record-ids) [Inserting data](https://surrealdb.com/learn/fundamentals/schemaless/inserting-data) [Reading data](https://surrealdb.com/learn/fundamentals/schemaless/reading-data) [Updating data](https://surrealdb.com/learn/fundamentals/schemaless/updating-data) [Deleting data](https://surrealdb.com/learn/fundamentals/schemaless/deleting-data) [Part 2: Adding relationships](https://surrealdb.com/learn/fundamentals/relationships) [Introduction](https://surrealdb.com/learn/fundamentals/relationships) [Graph relations](https://surrealdb.com/learn/fundamentals/relationships/graph-relations) [Record links](https://surrealdb.com/learn/fundamentals/relationships/record-links) [Relational style joins](https://surrealdb.com/learn/fundamentals/relationships/relational-style) [Part 3: Making it schemafull](https://surrealdb.com/learn/fundamentals/schemafull) [Introduction](https://surrealdb.com/learn/fundamentals/schemafull) [Define tables, views and changefeeds](https://surrealdb.com/learn/fundamentals/schemafull/define-table) [Define fields, constraints and assertions](https://surrealdb.com/learn/fundamentals/schemafull/define-fields) [Schemafull CRUD](https://surrealdb.com/learn/fundamentals/schemafull/schemafull-crud) [Part 4: Making it secure](https://surrealdb.com/learn/fundamentals/security) [Introduction](https://surrealdb.com/learn/fundamentals/security) [Authentication](https://surrealdb.com/learn/fundamentals/security/authentication) [Query capabilities](https://surrealdb.com/learn/fundamentals/security/query-capabilities) [Part 5: Making it performant](https://surrealdb.com/learn/fundamentals/performance) [Introduction](https://surrealdb.com/learn/fundamentals/performance) [Indexing & data model considerations](https://surrealdb.com/learn/fundamentals/performance/index-data-model) [Deployment & storage layer considerations](https://surrealdb.com/learn/fundamentals/performance/deployment-storage) [Completion](https://surrealdb.com/learn/fundamentals/completion) Certification Pending completion

# Reading data

Now that we've created some data, it's time to explore it.

In this lesson, we'll cover how to use

- The `SELECT` statement for both simple and advanced read operations, and how that compares to the `RETURN` statement.
- The `LET` statement for setting parameters to use in our statements.
- The `LIVE SELECT` statement for reading data in real-time as changes are made to the underlying table.

## Starting with the SQL select basics

Let's start with the foundations of a normal SQL `SELECT` statement.

Here are a few examples.

```
SELECT * FROM product;SELECT name FROM product;SELECT name AS product_name FROM product;
```

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

We can select everything from the `product` table with `SELECT * FROM product`. We can also just select specific fields by naming them, such as `SELECT name FROM product`. Finally, we can use `AS` to rename fields, such as changing `name` to `product_name`

You'll also find familiar SQL clauses such as `WHERE`, `GROUP BY`, `ORDER BY` and `LIMIT`.

### WHERE

We use the `WHERE` clause to filter for specific records, such as products which have the black pink colour.

```
SELECT * FROM productWHERE "Black Pink" IN colours;
```

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

### GROUP BY

`GROUP BY` is usually used alongside [aggregate functions](https://surrealdb.com/docs/reference/query-language/functions/database-functions#aggregate-functions), which are functions that can either be used on their own or in a statement with `GROUP BY` that aggregates data. In this example we are using it to find the number of orders and sales amount for each product.

```
SELECT    product_name,    count() AS number_of_orders,    math::sum(price * quantity) AS sum_salesFROM orderGROUP BY product_name;
```

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

A simple example to show how `GROUP BY` works is this one using the [count()](https://surrealdb.com/docs/reference/query-language/functions/database-functions/count) function. Here we want to find the number of orders. It's important to be aware that when counting the number of records in a table, most relational databases don't require you to use a `GROUP BY` since the data will never be nested.

In SurrealQL however, there is a lot more flexibility to model nested data. Therefore, we can't make the same assumptions as a relational database. This means functions like `count()` always go record by record unless you specify `GROUP ALL` which will use the entire table as one group.

```
-- Not aggregated: returns { count: 1 } for each recordSELECT count() FROM order;-- Aggregated: returns a single { count: 64 }SELECT count() FROM orderGROUP ALL;
```

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

### ORDER BY

`ORDER BY` is used to sort the records by a certain field. By default it sorts data in ascending order, but you can also specify `DESC` for descending order.

```
SELECT    product_name,    count() AS number_of_ordersFROM orderGROUP BY product_nameORDER BY number_of_orders DESC;
```

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

### LIMIT

Finally, the `LIMIT` clause is used to limit the number of records we get back from our query.

```
SELECT    product_name,    count() AS number_of_ordersFROM orderGROUP BY product_nameORDER BY number_of_orders DESCLIMIT 10;
```

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

## Moving onto more advanced features

Now that we've covered the foundations that most SQL dialects have, let's look into things specific to SurrealQL.

### Selecting a single record or a range of records

In most SQL dialects, you'd need to use the `WHERE` clause to filter by IDs or fields such as time.

```
SELECT name, emailFROM personWHERE id = person:01FTP9H7BG8VDANQPN8J3Y857R;SELECT name, emailFROM personWHERE id >= person:01FTP9H7BG8VDANQPN8J3Y857RAND id < person:01HG9EFC0R8DA8F87VNYP0CD8A;
```

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

In SurrealQL, the idiomatic way to fetch by record ID is to put the ID in the `FROM` clause rather than filtering with `WHERE`.

For a **single record**, `WHERE id = person:…` is valid SQL-style syntax and, since SurrealDB 3.0, the query planner optimises it to a direct key-value lookup, so the same path as `FROM person:…`. Even so, selecting directly by record ID is clearer and is the form we recommend.

For a **range of records**, `WHERE id >= … AND id < …` still tends to scan the table. Here you can use a [record range](https://surrealdb.com/docs/reference/query-language/language-primitives/data-types/record-ids#record-ranges) in the `FROM` clause instead, because it reads only the keys in that range from the key-value store.

```
SELECT name, emailFROM person:01FTP9H7BG8VDANQPN8J3Y857R;SELECT name, emailFROM person:01FTP9H7BG8VDANQPN8J3Y857R..01HG9EFC0R8DA8F87VNYP0CD8A;
```

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

SurrealQL also makes it easy to select what you need from a record, such as in cases where you want to select everything, but omit certain fields from a record.

```
-- Using omitSELECT * OMIT time FROM person:01FTP9H7BG8VDANQPN8J3Y857R;-- Not using omitSELECT id, first_name, last_name, name, email, phone, address,address_history, payment_detailsFROM person:01FTP9H7BG8VDANQPN8J3Y857R;
```

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

### Working with objects and arrays

The `SELECT` statement in SurrealQL is extremely flexible, with many advanced features. You can find a more comprehensive list of these features in our [documentation](https://surrealdb.com/docs/reference/query-language/statements/select), but for now, let's look at a few examples of how to work with objects and arrays.

For selecting and traversing objects and arrays and arrays of objects, we can use the dot and bracket notation.

```
-- Select the first colour in the colours arraySELECT colours[0]FROM product:01FSXKCPVR8G1TVYFT4JFJS5WB;-- Select updated_at from the time objectSELECT time.updated_atFROM product:01FSXKCPVR8G1TVYFT4JFJS5WB;-- Select the entire array of objectsSELECT imagesFROM product:01FSXKCPVR8G1TVYFT4JFJS5WB;-- Select all the URLs in the images array of objectsSELECT images.urlFROM product:01FSXKCPVR8G1TVYFT4JFJS5WB;-- Select the first URL in the images array of objectsSELECT images[0].urlFROM product:01FSXKCPVR8G1TVYFT4JFJS5WB;
```

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

Here are some notes on what those queries just did.

- We can select the first colour in the colours array using `colours[0]`
- We select `updated_at` from the time object using `time.updated_at`
- To select the first URL in the images array of objects, we use a combination of both, `images[0].url`

#### Object and array functions

Object and array functions are useful for many things such as deduplicating results similar to `SELECT DISTINCT` in most SQL dialects.

```
-- Returns the unique items in an arraySELECT array::distinct(sub_category) AS unique_sub_cat  FROM productGROUP ALL;-- Flattens and returns the unique items in an arraySELECT array::group(details) AS unique_detailsFROM productGROUP ALL;
```

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

There are a few ways of doing this in SurrealQL:

- Using [`array::distinct()`](https://surrealdb.com/docs/reference/query-language/functions/database-functions/array#arraydistinct), if the fields are not nested.
- Using [`array::flatten()`](https://surrealdb.com/docs/reference/query-language/functions/database-functions/array#arrayflatten), if the fields are nested.
- Using [`array::group()`](https://surrealdb.com/docs/reference/query-language/functions/database-functions/array#arraygroup), if you want to call flatten and distinct using a single method call.

Importantly, there is way to count things without using aggregate functions, if what you're counting is either an array or object. As then we can use `array::len()` or `object::len()` and get both aggregated data and non-aggregated data in one query.

```
-- Select the product name and the number of colours it hasSELECT  name,  array::len(colours) AS number_of_coloursFROM product;-- Select the person name and the number of address fieldsSELECT  name,  object::len(address) AS number_of_address_fieldsFROM person;
```

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

You can find many more useful functions in our [documentation](https://surrealdb.com/docs/reference/query-language/functions/database-functions).

### Tempfiles

There might be times where you want to run large analytics that have the potential to cause an out-of-memory error (OOM). That is where the `TEMPFILES` clause comes in, allowing you to process the query in temporary files on disk rather than in memory.

```
SELECT count() AS number_of_orders,time::format(time.created_at, "%Y-%m") AS month,math::sum(price * quantity) AS sum_sales, currencyFROM orderGROUP BY month, currencyORDER BY month DESCTEMPFILES;
```

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

This significantly reduces memory usage, though it's likely to also result in slower performance.

## Using `LET` parameters and subqueries

```
-- Find the name of the product where the price is higher than the avg priceSELECT name FROM productWHERE [price] > (  SELECT math::mean(price) AS avg_price FROM product GROUP ALL  ).avg_price;
```

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

Subqueries function in similar ways as you'd expect from SQL dialects, such as using them in the `SELECT`, `FROM` or `WHERE` clauses.
We'll cover them in more detail in part 2 on relational style joins.

```
-- Using the let statement to store the query resultLET $avg_price =  SELECT VALUE math::mean(price) AS avg_price FROM ONLY product GROUP ALL;-- Find the name of the product where the price is higher than the avg priceSELECT name from productWHERE price > $avg_price;
```

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

An alternative to using subqueries is often through using common table expressions (CTEs).

SurrealQL does not use typical CTEs, but we can use the `LET` statement to cover those use cases. We can also use the `LET` statement to parameterise our queries, either directly as static values, or dynamic values in combination with the `type` functions.

```
LET $field_name = "name";LET $table = "product";LET $id = "01FSXKCPVR8G1TVYFT4JFJS5WB";RETURN $table;SELECT type::field($field_name)FROM type::record($table, $id)
```

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

The `LET` statement can do a lot more than what we've covered here, as you can use it in almost every statement in SurrealQL and you can see more examples of that in our [documentation](https://surrealdb.com/docs/reference/query-language/statements/let).

## How `SELECT` compares to `RETURN`

Aside from the `SELECT` statement, you can also use the `RETURN` statement for reading data. A `RETURN` on its own just returns the value that follows it, and technically is almost never needed. That's because the value returned from a statement is its output, whether it is preceded by `RETURN` or not.

```
-- Return a number1337;RETURN 1337; SELECT * FROM ONLY 1337;
```

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

One situation where `RETURN` does make a difference though is when you want to use it to return a value from inside a block and skip the rest.

```
-- Returns 1337, skips the following query{    RETURN 1337;    SELECT name FROM person;};
```

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

Otherwise, you still might prefer to use it for the sake of readability. Even when adding `RETURN` before a value, it ends up being shorter than the combination of `FROM ONLY` and `SELECT VALUE` using the `SELECT` statement. I'd encourage you to experiment with the queries, removing the `ONLY` and or `VALUE` clause to see how the result changes.

```
-- Return a recordRETURN person:01FTP9H7BG8VDANQPN8J3Y857R.*;SELECT * FROM ONLY person:01FTP9H7BG8VDANQPN8J3Y857R;-- Return a field value inside the recordRETURN person:01FTP9H7BG8VDANQPN8J3Y857R.name;SELECT VALUE name FROM ONLY person:01FTP9H7BG8VDANQPN8J3Y857R;
```

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

You can see more examples of how to use the `RETURN` statement in code blocks, functions and transactions in our [documentation](https://surrealdb.com/docs/reference/query-language/statements/return).

## Going real-time with `LIVE SELECT`

`LIVE SELECT` allows us to unlock streaming data magic, through what we call live queries.

Live queries read data in real time, as changes are made to the underlying table.

```
-- Start a live queryLIVE SELECT * from product;-- Stop a live query by specifying its uuidKILL u"57f4964c-006f-463b-a965-19a3cec330b9";-- Start a live query using JSON patch formatLIVE SELECT DIFF from product;
```

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

When you run the `LIVE SELECT` in the CLI it will return a `UUID`, which is the live query unique ID. The `UUID` is used to keep track of the various live queries you have running and to stop them using the `KILL` statement.

Since SurrealDB Studio has live query listening built in, a `LIVE SELECT` will instead display the option to track the live query that you have just created.

Once you make changes to the table the live query is listening to, in our case the `product` table, you can see the live results updating.

You can either receive the changes in our normal format or use the `JSON PATCH` format by specifying `LIVE SELECT DIFF FROM product`.

You can see more details about live queries in our [documentation](https://surrealdb.com/docs/reference/query-language/statements/live-select).

## Summary

Let's quickly summarise what we've learned before I see you in the next lesson.

- The `SELECT` statement
  - Starts with the foundation of SQL, using familiar clauses such as `WHERE`, `GROUP BY`, `ORDER BY` and `LIMIT`.
  - Has more advanced features, such as selecting directly from a record ID or a record range in the `FROM` clause - the idiomatic way to avoid table scans when fetching by ID. It can also be used to work with objects and arrays.
  - Can use the `TEMPFILES` clause for processing the query in temporary files on disk rather than in memory. This is typically used for very large queries that might otherwise give an out-of-memory error (OOM).
- The `RETURN` statement
  - Can `RETURN` any value, from strings and numbers to entire code blocks and query results.
  - Can be used instead of the `SELECT` statement for some use cases, such as a more ergonomic way of returning values, replacing the `SELECT VALUE` and/or `FROM ONLY` from the `SELECT` statement.
  - Is actually just syntactic sugar, outside of usage in code blocks, functions and transactions to return early results.
- The `LIVE SELECT` statement
  - Reads data in real time as changes are made to the underlying table.
  - Will return a `UUID`, which is the live query unique ID. The `UUID` is used to keep track of the various live queries you have running and to stop them using the `KILL` statement.
  - Allows you to either receive the changes in our normal format or in `JSON PATCH` format by specifying `LIVE SELECT DIFF`.

Previous

Inserting data

[Previous](https://surrealdb.com/learn/fundamentals/schemaless/inserting-data)

Next lesson

Updating data

[Next lesson](https://surrealdb.com/learn/fundamentals/schemaless/updating-data)

```json
{"@context":"https://schema.org","@type":"Course","name":"SurrealDB Fundamentals","description":"The most efficient way to learn SurrealDB through guided hands-on learning","url":"https://surrealdb.com/learn/fundamentals","inLanguage":"en","isAccessibleForFree":false,"provider":{"@type":"Organization","name":"SurrealDB","url":"https://surrealdb.com"},"hasPart":[{"@type":"LearningResource","name":"SurrealDB Fundamentals","url":"https://surrealdb.com/learn/fundamentals"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals"},{"@type":"LearningResource","name":"Welcome to SurrealDB University","url":"https://surrealdb.com/learn/fundamentals/intro/welcome"},{"@type":"LearningResource","name":"Intro to SurrealDB","url":"https://surrealdb.com/learn/fundamentals/intro/surrealdb"},{"@type":"LearningResource","name":"Why SurrealQL is SQL-like","url":"https://surrealdb.com/learn/fundamentals/intro/surrealql"},{"@type":"LearningResource","name":"Part 1: Schemaless CRUD","url":"https://surrealdb.com/learn/fundamentals/schemaless"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals/schemaless"},{"@type":"LearningResource","name":"Record IDs","url":"https://surrealdb.com/learn/fundamentals/schemaless/record-ids"},{"@type":"LearningResource","name":"Inserting data","url":"https://surrealdb.com/learn/fundamentals/schemaless/inserting-data"},{"@type":"LearningResource","name":"Reading data","url":"https://surrealdb.com/learn/fundamentals/schemaless/reading-data"},{"@type":"LearningResource","name":"Updating data","url":"https://surrealdb.com/learn/fundamentals/schemaless/updating-data"},{"@type":"LearningResource","name":"Deleting data","url":"https://surrealdb.com/learn/fundamentals/schemaless/deleting-data"},{"@type":"LearningResource","name":"Part 2: Adding relationships","url":"https://surrealdb.com/learn/fundamentals/relationships"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals/relationships"},{"@type":"LearningResource","name":"Graph relations","url":"https://surrealdb.com/learn/fundamentals/relationships/graph-relations"},{"@type":"LearningResource","name":"Record links","url":"https://surrealdb.com/learn/fundamentals/relationships/record-links"},{"@type":"LearningResource","name":"Relational style joins","url":"https://surrealdb.com/learn/fundamentals/relationships/relational-style"},{"@type":"LearningResource","name":"Part 3: Making it schemafull","url":"https://surrealdb.com/learn/fundamentals/schemafull"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals/schemafull"},{"@type":"LearningResource","name":"Define tables, views and changefeeds","url":"https://surrealdb.com/learn/fundamentals/schemafull/define-table"},{"@type":"LearningResource","name":"Define fields, constraints and assertions","url":"https://surrealdb.com/learn/fundamentals/schemafull/define-fields"},{"@type":"LearningResource","name":"Schemafull CRUD","url":"https://surrealdb.com/learn/fundamentals/schemafull/schemafull-crud"},{"@type":"LearningResource","name":"Part 4: Making it secure","url":"https://surrealdb.com/learn/fundamentals/security"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals/security"},{"@type":"LearningResource","name":"Authentication","url":"https://surrealdb.com/learn/fundamentals/security/authentication"},{"@type":"LearningResource","name":"Query capabilities","url":"https://surrealdb.com/learn/fundamentals/security/query-capabilities"},{"@type":"LearningResource","name":"Part 5: Making it performant","url":"https://surrealdb.com/learn/fundamentals/performance"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals/performance"},{"@type":"LearningResource","name":"Indexing \u0026 data model considerations","url":"https://surrealdb.com/learn/fundamentals/performance/index-data-model"},{"@type":"LearningResource","name":"Deployment \u0026 storage layer considerations","url":"https://surrealdb.com/learn/fundamentals/performance/deployment-storage"},{"@type":"LearningResource","name":"Completion","url":"https://surrealdb.com/learn/fundamentals/completion"}]}
```

```json
{"@context":"https://schema.org","@type":"LearningResource","name":"Reading data","description":"Reading data","url":"https://surrealdb.com/learn/fundamentals/schemaless/reading-data","learningResourceType":"lesson","isPartOf":{"@type":"Course","name":"SurrealDB Fundamentals","url":"https://surrealdb.com/learn/fundamentals"},"position":10}
```

```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":"Reading data","item":"https://surrealdb.com/learn/fundamentals/schemaless/reading-data"}]}
```
