The schema defines the structure of documents in your Orama database. It specifies which fields are searchable and what type of data each field contains.
Schema Definition
Define a schema by mapping property names to their types:
import { create } from '@orama/orama'
const db = await create ({
schema: {
title: 'string' ,
description: 'string' ,
price: 'number' ,
inStock: 'boolean' ,
category: 'enum'
}
})
Supported Types
Orama supports the following field types:
Scalar Types
Type TypeScript Type Description Example stringstringFull-text searchable text "Wireless Headphones"numbernumberNumeric values with range queries 99.99booleanbooleanTrue/false values trueenumstring | numberEnumerated values (exact match) "electronics"geopoint{ lat: number, lon: number }Geographic coordinates { lat: 40.7128, lon: -74.0060 }
Array Types
All scalar types (except geopoint) support array variants:
const db = await create ({
schema: {
tags: 'string[]' , // Array of strings
ratings: 'number[]' , // Array of numbers
features: 'boolean[]' , // Array of booleans
categories: 'enum[]' // Array of enums
}
})
Vector Types
For semantic search and similarity matching:
const db = await create ({
schema: {
title: 'string' ,
embedding: 'vector[1536]' // 1536-dimensional vector
}
})
The number in brackets specifies the vector dimension. All vectors for a given property must have the same dimension.
Nested Objects
Schemas support nested object structures:
const db = await create ({
schema: {
title: 'string' ,
author: {
name: 'string' ,
email: 'string' ,
verified: 'boolean'
},
metadata: {
created: 'number' ,
tags: 'string[]'
}
}
})
Searching Nested Properties
Use dot notation to search nested properties:
const results = await search ( db , {
term: 'john' ,
properties: [ 'author.name' , 'author.email' ]
})
Filtering Nested Properties
const results = await search ( db , {
term: 'database' ,
where: {
'author.verified' : true ,
'metadata.created' : { gte: 1640000000 }
}
})
Type Inference
Orama provides full TypeScript type inference for your schema:
import { create , insert , search } from '@orama/orama'
const db = await create ({
schema: {
title: 'string' ,
price: 'number' ,
inStock: 'boolean'
}
})
// TypeScript knows the document structure
await insert ( db , {
title: 'Laptop' , // ✓ string
price: 999.99 , // ✓ number
inStock: true // ✓ boolean
// unknownField: 'x' // ✗ TypeScript error
})
const results = await search ( db , {
term: 'laptop'
})
// TypeScript knows the result structure
results . hits [ 0 ]. document . title // ✓ string
results . hits [ 0 ]. document . price // ✓ number
Schema Type Mappings
From types.ts:67-92, here’s how schema types map to TypeScript types:
type SchemaTypes < Value > =
Value extends 'string' ? string :
Value extends 'string[]' ? string [] :
Value extends 'boolean' ? boolean :
Value extends 'boolean[]' ? boolean [] :
Value extends 'number' ? number :
Value extends 'number[]' ? number [] :
Value extends 'enum' ? string | number :
Value extends 'enum[]' ? ( string | number )[] :
Value extends 'geopoint' ? Point :
Value extends `vector[ ${ number } ]` ? number [] :
Value extends object ? { [ Key in keyof Value ] : SchemaTypes < Value [ Key ]> } :
never
String vs Enum
Choose the right type for your use case:
Use string for:
Full-text search
Content that should be tokenized
Text with multiple words
Fuzzy matching
schema : {
title : 'string' , // "Wireless Bluetooth Headphones"
description : 'string' // "High-quality audio with..."
}
Use enum for:
Exact matching
Categories and tags
Single-word values
Filtering without tokenization
schema : {
category : 'enum' , // "electronics"
status : 'enum' , // "active"
priority : 'enum' // 1, 2, 3
}
Schema Validation
Orama validates documents against the schema during insertion:
const db = await create ({
schema: {
title: 'string' ,
price: 'number'
}
})
// ✓ Valid document
await insert ( db , {
title: 'Product' ,
price: 29.99
})
// ✗ Invalid: price should be number
await insert ( db , {
title: 'Product' ,
price: '29.99' // Error: type mismatch
})
Custom Validation
You can provide a custom validation function:
const db = await create ({
schema: { /* ... */ },
components: {
validateSchema : ( doc , schema ) => {
// Return property name if invalid, undefined if valid
if ( doc . price && doc . price < 0 ) {
return 'price'
}
return undefined
}
}
})
Searchable vs Sortable
All schema properties are searchable by default. For sorting configuration, see the Database page.
Array properties (string[], number[], etc.) cannot be used for sorting.
Enum and geopoint types also cannot be sorted.
Schema Immutability
Schemas are immutable after database creation. You cannot add or remove properties from an existing database.
To modify a schema:
Create a new database with the updated schema
Export data from the old database
Import data into the new database
import { create , insertMultiple , search } from '@orama/orama'
// Old database
const oldDb = await create ({
schema: { title: 'string' , price: 'number' }
})
// Get all documents
const allDocs = await search ( oldDb , { term: '' })
// New database with updated schema
const newDb = await create ({
schema: {
title: 'string' ,
price: 'number' ,
category: 'enum' // New field
}
})
// Migrate data
await insertMultiple ( newDb , allDocs . hits . map ( hit => ({
... hit . document ,
category: 'default'
})))
Next Steps
Documents Learn how to insert and manage documents
Search Start searching your data