• Start

Concepts & guides

Representations and codecs

Choose the right built-in when moving data between strings, bytes, tokens, patches, and executable query text.

Available since: v3.2.0

Many SurrealDB built-ins do the same broad job: take a value in representation A and produce a value in representation B. As these tend to be found over various parts of the documentation, this page is a map to introduce them in a single location and help you pick the right one.

I want to…UseReference
Serialise a value to JSON or CBOR (or Base64 bytes)encoding::json::*, encoding::cbor::*, encoding::base64::*Encoding functions
Parse JSON/CBOR bytes back into SurrealQL valuesencoding::json::decode, encoding::cbor::decodeEncoding functions
Preview how an analyzer tokenizes textsearch::analyzeSearch functions
Extract part of an email or URL stringparse::email::*, parse::url::*Parse functions
Diff or patch a value with JSON Patchvalue::diff, value::patchValue functions
Coerce or inspect typestype::*, casts (<datetime>, <bytes>, …)Type functions
Run a query string at runtimeeval::surql, eval::gqlEval functions

Reversible codecs for wire formats and storage:

Typical uses: DEFINE API request bodies, file bucket payloads, and SDK interchange. Round-trip is the mental model.

LET $payload = { event: 'signup', user: 'tobie' };

-- Value → JSON text → value again
encoding::json::decode(encoding::json::encode($payload));
-- { event: 'signup', user: 'tobie' }

Related one-way or format-specific helpers elsewhere include string::html::encode, geo::hash::encode, and crypto::* hashes.

search::analyze runs a named DEFINE ANALYZER pipeline on a string and returns an array of tokens. It is lossy (stemming, filtering) and mirrors what full-text indexing does — useful for debugging analyzers before you index.

The "format" here is not JSON or CBOR; it is whatever pipeline you defined on the analyzer.

DEFINE ANALYZER demo_blank TOKENIZERS blank;

search::analyze("demo_blank", "SurrealDB graph queries");
-- ['SurrealDB', 'graph', 'queries']

Compare the tokens above with what you get after adding FILTERS lowercase, snowball(english) — the same input string produces a different token list, which is why search::analyze is handy when tuning an analyzer before you create a FULLTEXT index.

parse::url::* and parse::email::* extract one component from a structured string. There is no round-trip — you get a field value, not a reassembled URL.

{
domain: parse::url::domain("https://surrealdb.com/docs"),
user: parse::email::user("tobie@surrealdb.com"),
};
-- { domain: 'surrealdb.com', user: 'tobie' }

value::diff and value::patch move between a SurrealQL value and JSON Patch operations. They pair naturally with changefeeds and LIVE SELECT DIFF.

LET $before = { title: 'Weekly update', status: 'draft' };
LET $after = { title: 'Weekly update', status: 'published' };
LET $patch = value::diff($before, $after);

value::patch($before, $patch);
-- { title: 'Weekly update', status: 'published' }

value::diff produced the patch; value::patch applied it. The same pair works when you receive patch operations from a client or a live diff stream.

Available since: v3.2.0

eval::surql and eval::gql parse and execute query text in the caller's transaction. That is fundamentally different from encoding:

  • Input is executable SurrealQL or ISO GQL, not a static wire format.

  • Denied by default — requires allow-eval-query and the arbitrary-query gate.

  • Nested writes affect the caller's transaction; transaction-control statements are rejected.

Use eval::* when the query string is only known at runtime. Prefer DEFINE FUNCTION, DEFINE API, or normal client queries when the shape of the work is fixed at deploy time.

-- Query text from a table, config row, or user input (requires allow-eval-query)
LET $template = "$greeting + ', ' + $name";
eval::surql($template, { greeting: 'Hello', name: 'world' });
-- 'Hello, world'

For ISO GQL strings, use eval::gql instead — same bindings object, plus the gql experimental capability. See Eval functions for setup and examples.

Was this page helpful?