Cerial
DecoratorsArray

@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 added

Generated 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:

ApproachMigrationDedupSortVALUE clause
@distinct @sortarray<T>Via VALUEVia VALUEYes
@setset<T>NativeNativeNo

@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@set requires [] 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.

On this page