• Start

Languages

/

JavaScript

/

API Reference

/

Data Types

Range

Generic range values for numeric, datetime, and other ordered types.

The Range class provides generic range values for representing inclusive or exclusive ranges of ordered data types.

Import:

import { Range, BoundIncluded, BoundExcluded } from 'surrealdb';

Source: value/range.ts

  • Beg - The type of the beginning bound

  • End - The type of the ending bound

Bounds are represented using BoundIncluded and BoundExcluded classes:

  • new BoundIncluded(value) — The bound includes the value

  • new BoundExcluded(value) — The bound excludes the value

  • undefined — Unbounded (no limit)

Type: Bound<T> = BoundIncluded<T> | BoundExcluded<T> | undefined

Create a new range value.

Syntax

new Range(begin, end)
ParameterTypeDescription
begin Bound<Beg>The beginning bound (can be inclusive, exclusive, or undefined for unbounded).
end Bound<End>The ending bound (can be inclusive, exclusive, or undefined for unbounded).
// Numeric range [1, 100]
const numericRange = new Range(
new BoundIncluded(1),
new BoundIncluded(100)
);

// Date range
const dateRange = new Range(
new BoundIncluded(new DateTime('2024-01-01')),
new BoundIncluded(new DateTime('2024-12-31'))
);

// Half-open range [0, 10)
const halfOpen = new Range(
new BoundIncluded(0),
new BoundExcluded(10)
);

The beginning bound of the range.

Type: Bound<Beg> — A BoundIncluded<Beg>, BoundExcluded<Beg>, or undefined

const range = new Range(
new BoundIncluded(1),
new BoundIncluded(10)
);

console.log(range.begin.value); // 1
console.log(range.begin instanceof BoundIncluded); // true

The ending bound of the range.

Type: Bound<End> — A BoundIncluded<End>, BoundExcluded<End>, or undefined

const range = new Range(
new BoundIncluded(1),
new BoundIncluded(10)
);

console.log(range.end.value); // 10
console.log(range.end instanceof BoundIncluded); // true

Convert to string representation.

Syntax

range.toString()

string - Range string (e.g., 1..10, 1..=10, 1>..10)

// Inclusive range [1, 10]
const inclusive = new Range(
new BoundIncluded(1),
new BoundIncluded(10)
);
console.log(inclusive.toString()); // '1..=10'

// Exclusive range (1, 10)
const exclusive = new Range(
new BoundExcluded(1),
new BoundExcluded(10)
);
console.log(exclusive.toString()); // '1>..10'

// Half-open [1, 10)
const halfOpen = new Range(
new BoundIncluded(1),
new BoundExcluded(10)
);
console.log(halfOpen.toString()); // '1..10'

Serialize for JSON.

Syntax

range.toJSON()

string - Range string representation

Check if two ranges are equal.

Syntax

range.equals(other)

boolean - True if equal

import { Surreal, Range, BoundIncluded } from 'surrealdb';

const db = new Surreal();
await db.connect('ws://localhost:8000');

// Define age range for filtering
const adultRange = new Range(
new BoundIncluded(18),
new BoundIncluded(120)
);

// Query with range
const adults = await db.query(`
SELECT * FROM users
WHERE age IN $range
`, {
range: adultRange
}).collect();
import { DateTime, Range, BoundIncluded } from 'surrealdb';

// Define fiscal year
const fiscalYear = new Range(
new BoundIncluded(new DateTime('2024-01-01T00:00:00Z')),
new BoundIncluded(new DateTime('2024-12-31T23:59:59Z'))
);

// Query events in date range
const events = await db.query(`
SELECT * FROM events
WHERE date IN $range
`, {
range: fiscalYear
}).collect();
import { Decimal, Range, BoundIncluded } from 'surrealdb';

// Define price range for product filtering
const budgetRange = new Range(
new BoundIncluded(new Decimal('0')),
new BoundIncluded(new Decimal('100'))
);

const products = await db.query(`
SELECT * FROM products
WHERE price IN $range
`, {
range: budgetRange
}).collect();
import { Range, BoundIncluded } from 'surrealdb';

// Grade ranges
const gradeA = new Range(
new BoundIncluded(90),
new BoundIncluded(100)
);

const gradeB = new Range(
new BoundIncluded(80),
new BoundIncluded(89)
);

// Assign grades
const students = await db.query(`
SELECT *,
CASE
WHEN score IN $gradeA THEN 'A'
WHEN score IN $gradeB THEN 'B'
ELSE 'C'
END AS grade
FROM students
`, {
gradeA,
gradeB
}).collect();
import { DateTime, Duration, Range, BoundIncluded } from 'surrealdb';

// Recent activity (last 30 days)
const now = DateTime.now();
const thirtyDaysAgo = now.sub(new Duration('30d'));

const recentRange = new Range(
new BoundIncluded(thirtyDaysAgo),
new BoundIncluded(now)
);

const recentActivity = await db.query(`
SELECT * FROM activity_log
WHERE timestamp IN $range
ORDER BY timestamp DESC
`, {
range: recentRange
}).collect();
import { RecordId, Range, BoundIncluded, BoundExcluded } from 'surrealdb';

// Fetch records in ID range
const idRange = new Range(
new BoundIncluded(new RecordId('users', 'a')),
new BoundExcluded(new RecordId('users', 'f'))
);

const users = await db.query(`
SELECT * FROM users
WHERE id IN $range
`, {
range: idRange
}).collect();
import { Range, BoundExcluded } from 'surrealdb';

// Exclusive range (not including boundaries)
const exclusive = new Range(
new BoundExcluded(0),
new BoundExcluded(100)
);
// Matches: 0 < x < 100

const results = await db.query(`
SELECT * FROM measurements
WHERE value IN $range
`, {
range: exclusive
}).collect();
import { Range, BoundIncluded, BoundExcluded } from 'surrealdb';

// Half-open range [start, end)
const halfOpen = new Range(
new BoundIncluded(0),
new BoundExcluded(10)
);
// Matches: 0 <= x < 10

// Common for array-like indexing
const items = await db.query(`
SELECT * FROM items
WHERE index IN $range
`, {
range: halfOpen
}).collect();
import { Range, BoundIncluded } from 'surrealdb';

// Define multiple severity levels
const low = new Range(
new BoundIncluded(0),
new BoundIncluded(3)
);

const medium = new Range(
new BoundIncluded(4),
new BoundIncluded(6)
);

const high = new Range(
new BoundIncluded(7),
new BoundIncluded(10)
);

// Query by severity
const criticalIssues = await db.query(`
SELECT * FROM issues
WHERE severity IN $range
`, {
range: high
}).collect();
import { Range, BoundIncluded, BoundExcluded, DateTime } from 'surrealdb';

function queryByRange<T>(
start: T,
end: T,
inclusive: boolean = true
): Range<T, T> {
return new Range(
new BoundIncluded(start),
inclusive ? new BoundIncluded(end) : new BoundExcluded(end)
);
}

// Usage
const dateRange = queryByRange(
new DateTime('2024-01-01'),
new DateTime('2024-12-31')
);

const orders = await db.query(`
SELECT * FROM orders
WHERE created_at IN $range
`, {
range: dateRange
}).collect();

SurrealDB uses specific notation for ranges:

NotationDescriptionExample
a..=bInclusive both ends [a, b]1..=10
a..bInclusive start, exclusive end [a, b)1..10
a>..bExclusive start, exclusive end (a, b)1>..10
a>..=bExclusive start, inclusive end (a, b]1>..=10
// Good: Inclusive for dates (including full days)
const dateRange = new Range(
new BoundIncluded(new DateTime('2024-01-01T00:00:00Z')),
new BoundIncluded(new DateTime('2024-01-31T23:59:59Z'))
);

// Good: Exclusive end for array-like indexing
const arrayRange = new Range(
new BoundIncluded(0),
new BoundExcluded(10)
); // [0, 10)
// Good: Explicit types
const range: Range<number, number> = new Range(
new BoundIncluded(1),
new BoundIncluded(100)
);

// Good: Consistent types
const dateRange: Range<DateTime, DateTime> = new Range(
new BoundIncluded(DateTime.now()),
new BoundIncluded(DateTime.now().add(new Duration('1d')))
);
// Good: Ensure start <= end
function createRange<T>(start: T, end: T): Range<T, T> | null {
if (start > end) {
console.error('Invalid range: start must be <= end');
return null;
}

return new Range(
new BoundIncluded(start),
new BoundIncluded(end)
);
}
  • Filtering - Filter records by numeric, date, or other ordered values

  • Pagination - Query records in ID ranges

  • Time Windows - Define time-based query windows

  • Price Filtering - E-commerce price range searches

  • Score Categorization - Categorize by score ranges (grades, ratings)

  • Geographic Bounds - Coordinate ranges for maps

Was this page helpful?