String Functions (string::)
String Functions (string::*)
Level 6 — Advanced Querying & Functions The standard library module in SurrealDB dedicated to text manipulation, inspection, formatting, and validation (
string::len(),string::lowercase(),string::slug(),string::is::email()).
1. Prerequisites
- Built-in Functions Overview — The parent library context.
string— The UTF-8 string data type.
2. Term Category
Query Feature (string transformation & regex builtin functions): - Database Command / Tool
3. Explanation
(1) Design Motivation — "Why did we design this?"
Text processing is one of the most common tasks in web applications:
- Normalizing user input (e.g. converting emails to lowercase before saving).
- Generating URL-friendly slugs for blog titles (
"My First Post!""my-first-post"). - Validating inputs (e.g. verifying email formats, checking string lengths).
In traditional databases, developers often perform these text transformations in backend API middleware (like Node.js) before sending queries to the database.
We designed the string::* module in SurrealDB to bring comprehensive text utilities directly into the query engine. With functions for transformation, trimming, splitting, slug generation, and validation (string::is::*), you can format and validate text at the database layer in single declarative statements.
(2) Key Function Categories
1. Transformations & Formatting
string::lowercase(val)/string::uppercase(val): Case conversions.string::trim(val): Trims leading and trailing whitespace.string::slug(val): Converts text to a clean URL slug (e.g.,"Hello World!""hello-world").string::concat(str1, str2, ...): Concatenates text strings together.string::replace(val, search, replace): Replaces text occurrences.
2. Inspection & Length
string::len(val): Returns character count (Unicode-aware).string::slice(val, start, len): Extracts a substring range.string::contains(val, search): Checks if a substring exists (case-sensitive).
3. Validation Helpers (string::is::*)
string::is::email(val): Returnstrueif string is a valid email.string::is::url(val): Returnstrueif string is a valid URL.string::is::uuid(val): Validates UUID string formatting.
(3) Reality Metaphor (The Text Publishing Desk)
Imagine an editor's desk in a publishing house:
string::trim: Brushing off loose paper dust from the edges of a manuscript page.string::slug: Stamping a clean, hyphenated library tracking label onto the spine.string::is::email: A proofreader verifying that an address card has a valid@symbol and domain before filing it.
(4) Code Examples
Using string::* Functions in SurrealQL
-- 1. Slug generation and case normalization on CREATE/UPDATE
CREATE post SET
title = "SurrealDB 2.0 Released!",
slug = string::slug("SurrealDB 2.0 Released!");
-- Result: slug = "surrealdb-2-0-released"
-- 2. Normalizing emails inside field definitions
DEFINE FIELD email ON user TYPE string
VALUE string::lowercase(string::trim($value))
ASSERT string::is::email($value);
-- 3. Querying string lengths and substrings
SELECT
title,
string::len(content) AS char_count,
string::slice(content, 0, 50) AS preview
FROM article;
4. Common Mistakes & Pitfalls
Mistake 1: Using 'string::len()' inside ASSERT constraints for optional fields without a 'NONE' bypass check
The mistake: Defining DEFINE FIELD bio ON user TYPE option<string> ASSERT string::len($value) <= 140;.
Why it's wrong: If a user omits bio, $value is NONE. Calling string::len(NONE) fails because NONE is not a string, causing validation errors on optional field writes.
Fix: Always check $value = NONE OR ... when using string functions inside optional field assertions:
-- GOOD (Bypasses check if NONE)
DEFINE FIELD bio ON user TYPE option<string>
ASSERT $value = NONE OR string::len($value) <= 140;
Mistake 2: Passing Non-String Primitives to string:: Functions
The mistake: Executing string::lowercase(123) passing a number.
Why it's wrong: Functions in string:: namespace expect string inputs. Pass <string> 123 or use type::string() to convert numbers first.
Incorrect:
RETURN string::lowercase(123); // ❌ Expected string, got number!
Fix:
RETURN string::lowercase(<string> 123);
Mistake 3: Using Invalid Substring Index Out of Bounds in string::slice()
The mistake: Passing negative indices or out of bound start positions.
Why it's wrong: Check string lengths with string::len() before slicing to avoid invalid slice ranges.
Incorrect:
LET $str = "hi"; RETURN string::slice($str, 10, 20);
Fix:
LET $str = "hi"; RETURN string::slice($str, 0, string::len($str));
5. Practice Exercises
Exercise 1: String Normalization and Trimming
Scenario:
Sanitize user profile input " JANE DOE " by trimming whitespace and converting to title slug format using string::slug().
Requirements:
- Apply
string::slug(string::trim(" JANE DOE ")).
Answer
Implementation
SELECT string::slug(string::trim(" JANE DOE ")) AS user_slug;
-- Output: "jane-doe"
Technical Explanation
string::trim()removes leading and trailing whitespace.string::slug()converts string text into URL-friendly slug strings ("jane-doe").- Automates URL slug generation directly inside database queries.
Exercise 2: String Substring and Length Inspections
Scenario:
Inspect string length using string::len() and extract the first 5 characters using string::slice().
Requirements:
- Test
string::len("SurrealDB"). - Test
string::slice("SurrealDB", 0, 7).
Answer
Implementation
SELECT
string::len("SurrealDB") AS total_len,
string::slice("SurrealDB", 0, 7) AS sub_str;
Technical Explanation
string::len()returns UTF-8 character counts accurately.string::slice(str, start, end)extracts character range substrings.- Enables string parsing and truncation server-side.
Exercise 3: String Replacement & Pattern Matching
Scenario:
Replace all occurrences of "PostgreSQL" with "SurrealDB" in a description text using string::replace().
Requirements:
- Execute
string::replace("Migrating from PostgreSQL to PostgreSQL", "PostgreSQL", "SurrealDB").
Answer
Implementation
SELECT string::replace("Migrating from PostgreSQL to PostgreSQL", "PostgreSQL", "SurrealDB") AS updated_text;
-- Output: "Migrating from SurrealDB to SurrealDB"
Technical Explanation
string::replace(str, pattern, replacement)replaces all matching string occurrences.- Performs global text replacement natively inside the database.
- Useful for content migration and text transformations.
6. Related Terms
- Built-in Functions Overview — The parent library.
string— The string data type.
7. Key Takeaways
- The
string::*module provides text formatting, inspection, and validation utilities. string::slug()generates URL-safe slugs from strings automatically.string::is::*functions validate emails, URLs, and UUID strings.- Fully UTF-8 and Unicode aware (correctly handles multi-byte characters and emojis).
- Ideal for use inside
DEFINE FIELD ... VALUEandASSERTclauses.