Facets
Facets allow users to narrow down search results by specific attributes or characteristics. They provide aggregated counts of values for properties in your search results, enabling dynamic filtering options.
What are Facets?
Facets are aggregations that show how many documents in your search results have specific values for a given property. They’re commonly used in e-commerce sites for filtering by category, price range, brand, etc.
Basic Facets
Add facets to your search by specifying the facets parameter:
import { create , insert , search } from '@orama/orama'
const db = create ({
schema: {
title: 'string' ,
description: 'string' ,
category: 'string' ,
price: 'number'
}
})
insert ( db , {
title: 'Wireless Headphones' ,
description: 'Premium wireless headphones' ,
category: 'electronics' ,
price: 99.99
})
const results = search ( db , {
term: 'headphones' ,
facets: {
category: {
limit: 10 ,
sort: 'ASC'
}
}
})
Facet Response
Facets are returned in the search results under the facets property:
{
count : 10 ,
hits : [ ... ],
elapsed : { raw : 123456 , formatted : '123μs' },
facets : {
category : {
count : 3 ,
values : {
'electronics' : 5 ,
'audio' : 3 ,
'accessories' : 2
}
}
}
}
The total number of unique values for this facet
An object mapping each unique value to its occurrence count
Facet Types
String Facets
String facets aggregate unique string values and their counts:
const results = search ( db , {
term: 'Personal Computer' ,
facets: {
'category.primary' : {
limit: 10 , // Maximum number of facet values to return
offset: 0 , // Skip first N values
sort: 'ASC' // Sort order: 'ASC', 'DESC', 'asc', 'desc'
}
}
})
Maximum number of facet values to return
Number of facet values to skip (for pagination)
sort
'ASC' | 'DESC' | 'asc' | 'desc'
default: "'DESC'"
Sort order for facet values by count
Number Facets
Number facets aggregate counts within specified ranges:
const results = search ( db , {
term: 'headphones' ,
facets: {
price: {
ranges: [
{ from: 0 , to: 50 },
{ from: 50 , to: 100 },
{ from: 100 , to: 200 },
{ from: 200 , to: 500 }
]
}
}
})
Response:
{
facets : {
price : {
count : 4 ,
values : {
'0-50' : 12 ,
'50-100' : 25 ,
'100-200' : 18 ,
'200-500' : 5
}
}
}
}
ranges
Array<{from: number, to: number}>
required
Array of range objects defining the buckets for aggregation
Boolean Facets
Boolean facets aggregate true/false counts:
const db = create ({
schema: {
title: 'string' ,
inStock: 'boolean' ,
featured: 'boolean'
}
})
const results = search ( db , {
term: 'headphones' ,
facets: {
inStock: {
true: true ,
false: true
},
featured: {
true: true
}
}
})
Response:
{
facets : {
inStock : {
count : 2 ,
values : {
'true' : 15 ,
'false' : 5
}
},
featured : {
count : 1 ,
values : {
'true' : 8
}
}
}
}
Include count of true values
Include count of false values
Multiple Facets
You can request multiple facets in a single search:
const results = search ( db , {
term: 'laptop' ,
facets: {
category: {
limit: 10 ,
sort: 'DESC'
},
brand: {
limit: 20 ,
sort: 'DESC'
},
price: {
ranges: [
{ from: 0 , to: 500 },
{ from: 500 , to: 1000 },
{ from: 1000 , to: 2000 }
]
},
inStock: {
true: true ,
false: true
}
}
})
Nested Property Facets
Facets work with nested object properties:
const db = create ({
schema: {
title: 'string' ,
category: {
primary: 'string' ,
secondary: 'string'
},
meta: {
brand: 'string'
}
}
})
const results = search ( db , {
term: 'product' ,
facets: {
'category.primary' : {
limit: 10 ,
sort: 'DESC'
},
'category.secondary' : {
limit: 10
},
'meta.brand' : {
limit: 20
}
}
})
Facets with Filters
Combine facets with filters to show available options for the current filter state:
const results = search ( db , {
term: 'headphones' ,
where: {
price: {
lt: 100
}
},
facets: {
category: {
limit: 10
},
brand: {
limit: 10
}
}
})
Facets are calculated after filters are applied, showing only the values available in the filtered result set.
Facets with Different Search Modes
Full-Text Search
const results = search ( db , {
term: 'headphones' ,
mode: 'fulltext' ,
facets: {
category: { limit: 10 }
}
})
Vector Search
const results = search ( db , {
mode: 'vector' ,
vector: {
value: embeddings ,
property: 'embedding'
},
facets: {
category: { limit: 10 }
}
})
Hybrid Search
const results = search ( db , {
mode: 'hybrid' ,
term: 'headphones' ,
vector: {
value: embeddings ,
property: 'embedding'
},
facets: {
category: { limit: 10 },
price: {
ranges: [
{ from: 0 , to: 100 },
{ from: 100 , to: 200 }
]
}
}
})
For hybrid search, facets include results from both full-text and vector searches.
Preflight Queries with Facets
Get facets without fetching full documents:
const results = search ( db , {
term: 'headphones' ,
preflight: true ,
facets: {
category: { limit: 10 },
price: {
ranges: [
{ from: 0 , to: 100 },
{ from: 100 , to: 200 }
]
}
}
})
console . log ( results )
// {
// elapsed: { raw: 181208, formatted: '181μs' },
// count: 100,
// facets: { ... }
// }
Preflight queries with facets are useful for building filter UIs before loading results.
Limit Facet Values
Request only the number of facet values you need: facets : {
category : {
limit : 10 // Only get top 10 categories
}
}
Use Appropriate Ranges
For number facets, choose ranges that make sense for your data: facets : {
price : {
ranges : [
{ from: 0 , to: 50 },
{ from: 50 , to: 100 },
// Avoid too many small ranges
]
}
}
Index Faceted Properties
All properties are automatically indexed, but consider if you need facets on every property
Combine with Preflight
Use preflight queries to get facets without document overhead: search ( db , {
term: 'query' ,
preflight: true ,
facets: { category: { limit: 10 } }
})
Building Filter UIs
Facets are perfect for building dynamic filter interfaces:
// 1. Initial search with facets
const initialResults = search ( db , {
term: 'headphones' ,
facets: {
category: { limit: 10 },
brand: { limit: 20 },
price: {
ranges: [
{ from: 0 , to: 50 },
{ from: 50 , to: 100 },
{ from: 100 , to: 200 }
]
},
inStock: { true: true , false: true }
}
})
// 2. User selects a filter
const filteredResults = search ( db , {
term: 'headphones' ,
where: {
category: 'wireless' ,
price: {
between: [ 50 , 100 ]
}
},
facets: {
brand: { limit: 20 },
inStock: { true: true , false: true }
}
})
// 3. Facets now show only available options for filtered results
Common Use Cases
E-commerce Filters Build category, brand, price, and attribute filters
Content Analytics Analyze content distribution by category, author, or date
Search Refinement Help users narrow down large result sets
Data Exploration Understand data distribution and patterns
Filters Apply filters to search results
Full-Text Search Combine facets with text search
Sorting Sort faceted results
Hybrid Search Use facets with hybrid search