@set
Convert array fields to SurrealDB set types with automatic deduplication and sorting.
Converts an array field to a SurrealDB set type. Sets automatically deduplicate and sort their elements at the database level, eliminating the need for separate @distinct and @sort decorators.
Syntax
model Article {
id Record @id
title String
tags String[] @set
scores Int[] @set
}Behavior
SurrealDB set<T> handles deduplication and sorting natively. Duplicate values are silently removed, and elements are kept in sorted order.
await db.Article.create({
data: { title: 'Hello', tags: ['typescript', 'go', 'typescript', 'alpha'] },
});
// tags stored as: ['alpha', 'go', 'typescript'] — deduplicated and sorted
await db.Article.updateMany({
where: { id: articleId },
data: { tags: { push: 'go' } },
});
// tags still: ['alpha', 'go', 'typescript'] — duplicate not addedGenerated Types
The output type uses CerialSet<T> (a branded array type), while input types accept regular arrays:
// Output type
interface Article {
tags: CerialSet<string>; // branded — deduplicated and sorted
scores: CerialSet<number>;
}
// Input/Create type — regular arrays
interface ArticleInput {
tags: string[]; // SurrealDB handles dedup/sort
scores: number[];
}vs @distinct and @sort
@set replaces the combination of @distinct @sort with native SurrealDB set semantics:
| Approach | Migration | Dedup | Sort | VALUE clause |
|---|---|---|---|---|
@distinct @sort | array<T> | Via VALUE | Via VALUE | Yes |
@set | set<T> | Native | Native | No |
@set cannot be combined with @distinct or @sort — sets inherently provide both behaviors.
Use @set when you want automatic deduplication and sorting. Use @distinct or @sort alone when you only need one behavior.
Restrictions
- Array fields only —
@setrequires[]on the field type - Primitive types only — Allowed on
String[],Int[],Float[],Bool[],Date[],Uuid[],Duration[],Number[],Bytes[],Geometry[],Any[] - Not on Decimal[] — SurrealDB has known issues with
set<decimal> - Not on Object[], Tuple[], Record[] — Only primitive array types are supported
- Not with @distinct — Redundant, sets are inherently distinct
- Not with @sort — Redundant, sets are inherently sorted
Applicable Types
model Example {
id Record @id
strings String[] @set
ints Int[] @set
floats Float[] @set
bools Bool[] @set
dates Date[] @set
uuids Uuid[] @set
durations Duration[] @set
numbers Number[] @set
bytes Bytes[] @set
geometries Geometry[] @set
anyValues Any[] @set
}On Object Fields
@set can be applied to array fields within object definitions:
object ContactInfo {
email Email
tags String[] @set
}
model User {
id Record @id
contact ContactInfo
}The deduplication and sorting are enforced at the database level, just like on model fields.
Implementation Detail
Cerial automatically wraps set field values with a <set> cast in generated queries. SurrealDB 3.x doesn't auto-coerce arrays to sets, so this cast ensures values are properly stored as sets even when passed as regular arrays.