SPLIT Clause
SPLIT Clause
Level 6 — Advanced Querying & Functions The SurrealQL query modifier appended to
SELECTstatements that deconstructs an array field into multiple output records (one per array item), equivalent to MongoDB's$unwindaggregation stage.
1. Prerequisites
2. Term Category
Query Feature (array record flattening SPLIT clause): - Database Command / Tool
3. Explanation
(1) Design Motivation — "Why did we design this?"
In document databases (MongoDB) and multi-model databases, records often store arrays of items (e.g. a blog post storing tags: ["rust", "tech", "database"]).
If you want to perform aggregations on individual array items—such as counting how many total posts use each tag across all users—you cannot group by the array directly (grouping by tags groups by the exact combination of tags).
In MongoDB, you solve this using the $unwind aggregation stage. In SQL (PostgreSQL), you use UNNEST(array_column).
We designed the SPLIT clause in SurrealQL to provide a clean, readable way to deconstruct arrays inside queries. Appending SPLIT <field_name> to a SELECT query instructs SurrealDB to expand the array, emitting one separate output row for each item in the array while preserving the surrounding record properties.
(2) Transformation Visualized
Input Record:
{ "id": "post:1", "title": "SurrealDB News", "tags": ["rust", "database"] }
Query: SELECT title, tags FROM post SPLIT tags;
Output Records:
[
{ "title": "SurrealDB News", "tags": "rust" },
{ "title": "SurrealDB News", "tags": "database" }
]
(3) Reality Metaphor (Deck of Cards)
Imagine holding a card deck:
- Array Field: A single Box of Cards labeled "Tags" resting on a desk. The box is 1 item.
SPLITClause: Unboxing the deck and dealing out individual cards side-by-side across the table. Each card gets its own spot, but keeps a sticker pointing back to the original box name.
(4) Code Examples
Using SPLIT in SurrealQL
-- 1. Simple SPLIT query: Flatten tags array for all posts
SELECT title, tags FROM post SPLIT tags;
-- 2. Combine SPLIT with GROUP BY to count tag popularity across the entire database!
SELECT
tags AS tag_name,
count() AS usage_count
FROM post
SPLIT tags
GROUP BY tag_name
ORDER BY usage_count DESC;
-- 3. SPLIT on nested array properties
SELECT name, hobbies FROM user SPLIT hobbies;
4. Common Mistakes & Pitfalls
Mistake 1: Attempting to use SPLIT on a non-array field, expecting array transformation behavior
The mistake: Running SELECT * FROM user SPLIT email; where email is a scalar string "alice@example.com".
Why it's wrong: SPLIT operates on array or set container types. When applied to a scalar string or number, SurrealDB treats it as a single-element list or ignores the split, returning the record unchanged.
Fix: Ensure the target field passed to SPLIT is an array or set data type.
Mistake 2: Using SPLIT on Non-Array Fields
The mistake: Executing SELECT * FROM article SPLIT title; when title is a scalar string.
Why it's wrong: SPLIT ON field expects an array field. It splits array elements into separate distinct result record rows.
Incorrect:
SELECT * FROM article SPLIT title; // ❌ Title is string, not array!
Fix:
SELECT * FROM article SPLIT tags; // Correct: 'tags' is an array<string>
Mistake 3: Confusing SPLIT ON Data Clause with String Splitting string::split()
The mistake: Using SPLIT ON text expecting to split a string by spaces.
Why it's wrong: SPLIT ON field splits array records into multiple row records. To split text strings by delimiter, use function string::split(text, delimiter).
Incorrect:
SELECT * FROM user SPLIT bio; // ❌ Does not tokenize string!
Fix:
RETURN string::split("a,b,c", ","); // Tokenizes string into array
5. Practice Exercises
Exercise 1: Unnesting Array Fields into Separate Records
Scenario:
An analytics query takes records containing an array of tags tags = ["rust", "db"] and unnests them into separate result records using SPLIT ON.
Requirements:
- Create
article:a1withtags = ["rust", "db"]. - Execute
SELECT title, tags FROM article SPLIT ON tags.
Answer
Implementation
CREATE article:a1 SET title = "SurrealQL Basics", tags = ["rust", "db"];
-- Unnest array field into separate result records
SELECT title, tags FROM article SPLIT ON tags;
-- Output:
-- [ { title: "SurrealQL Basics", tags: "rust" }, { title: "SurrealQL Basics", tags: "db" } ]
Technical Explanation
SPLIT ON fieldexpands array elements, outputting a separate result document for each array item.- Replaces SQL
UNNEST()and MongoDB$unwindaggregation pipeline stages. - Facilitates per-item aggregation and reporting queries.
Exercise 2: Grouping After Array Unnesting
Scenario:
Unnest tags arrays across all articles using SPLIT ON, then group by individual tag to count occurrences.
Requirements:
- Unnest
SPLIT ON tags. - Group by
tagsand calculatecount().
Answer
Implementation
CREATE article:a1 SET tags = ["rust", "db"];
CREATE article:a2 SET tags = ["rust", "web"];
SELECT tags AS tag, count() AS total
FROM article
SPLIT ON tags
GROUP BY tag;
Technical Explanation
- Combining
SPLIT ONwithGROUP BYaggregates individual array items across records. - Counts how many documents contain each distinct array tag item.
- Simplifies tag cloud and category count reporting queries.
Exercise 3: Multi-Array Unnesting Considerations
Scenario:
Explain the behavior of applying SPLIT ON across multiple array fields simultaneously.
Requirements:
- Describe how
SPLIT ON field1, field2expands cartesian product combinations.
Answer
Implementation
CREATE post:p1 SET categories = ["tech", "news"], authors = ["Alice", "Bob"];
-- Cartesian product unnesting
SELECT * FROM post SPLIT ON categories, authors;
Technical Explanation
- Splitting on multiple array fields generates a cartesian product expansion of all array combinations.
- Outputs result records for array lengths and .
- Use carefully on large arrays to prevent result set explosion.
6. Related Terms
SELECT— The query statement.- Array Functions (
array::*) — Manipulating arrays. FORExpression — Related concept:FORExpression.
7. Key Takeaways
- The
SPLITclause expands array elements into separate output records. - Direct equivalent to MongoDB's
$unwindand PostgreSQL'sUNNEST(). - Essential step before running
GROUP BYaggregations on individual array items. - Preserves outer record fields across all expanded output rows.
- Operates on
arrayandsetdata types.