Sorting
Orama allows you to sort search results by any indexed property in ascending or descending order. You can also use custom sorting functions for advanced use cases.
Basic Sorting
Use the sortBy parameter to sort results by a property:
import { create , insert , search } from '@orama/orama'
const db = create ({
schema: {
title: 'string' ,
price: 'number' ,
rating: 'number'
}
})
insert ( db , {
title: 'Wireless Headphones' ,
price: 99.99 ,
rating: 4.5
})
const results = search ( db , {
term: 'headphones' ,
sortBy: {
property: 'price' ,
order: 'ASC'
}
})
Sort Parameters
The property to sort by. Must be a sortable property in your schema.
sortBy.order
'ASC' | 'DESC'
default: "'DESC'"
Sort order: 'ASC' for ascending, 'DESC' for descending
Sortable Property Types
Orama supports sorting on the following property types:
Number Properties
String Properties
Boolean Properties
const results = search ( db , {
term: 'product' ,
sortBy: {
property: 'price' ,
order: 'ASC' // Lowest to highest
}
})
Vector properties and enum arrays cannot be used for sorting.
Sort Order
Ascending Order
Sort from smallest to largest (numbers), A-Z (strings), or false to true (booleans):
const results = search ( db , {
term: 'headphones' ,
sortBy: {
property: 'price' ,
order: 'ASC'
}
})
// Results: $10, $20, $50, $100, $200
Descending Order
Sort from largest to smallest (numbers), Z-A (strings), or true to false (booleans):
const results = search ( db , {
term: 'headphones' ,
sortBy: {
property: 'price' ,
order: 'DESC'
}
})
// Results: $200, $100, $50, $20, $10
Nested Property Sorting
Sort by nested object properties:
const db = create ({
schema: {
title: 'string' ,
meta: {
rating: 'number' ,
reviews: 'number'
}
}
})
const results = search ( db , {
term: 'product' ,
sortBy: {
property: 'meta.rating' ,
order: 'DESC'
}
})
Default Sorting Behavior
When sortBy is not specified, results are sorted by relevance score:
const results = search ( db , {
term: 'headphones'
// Results sorted by BM25 score (most relevant first)
})
Without explicit sorting, Orama uses BM25 scoring for full-text search and cosine similarity for vector search to rank results.
Custom Sorting Functions
For advanced sorting needs, provide a custom sorting function:
const results = search ( db , {
term: 'headphones' ,
sortBy : ( a , b ) => {
const [ idA , scoreA , docA ] = a
const [ idB , scoreB , docB ] = b
// Sort by price, then by rating if prices are equal
if ( docA . price !== docB . price ) {
return docA . price - docB . price // Ascending by price
}
return docB . rating - docA . rating // Descending by rating
}
})
Custom Function Parameters
The custom function receives two arguments, each containing:
Custom Function Examples
Multi-field Sorting
Sort by Computed Value
Sort by Relevance and Property
const results = search ( db , {
term: 'product' ,
sortBy : ( a , b ) => {
const [, , docA ] = a
const [, , docB ] = b
// First by inStock (true first)
if ( docA . inStock !== docB . inStock ) {
return docB . inStock - docA . inStock
}
// Then by rating (highest first)
if ( docA . rating !== docB . rating ) {
return docB . rating - docA . rating
}
// Finally by price (lowest first)
return docA . price - docB . price
}
})
Sorting with Different Search Modes
Full-Text Search
const results = search ( db , {
term: 'headphones' ,
mode: 'fulltext' ,
sortBy: {
property: 'price' ,
order: 'ASC'
}
})
Vector Search
const results = search ( db , {
mode: 'vector' ,
vector: {
value: embeddings ,
property: 'embedding'
},
sortBy: {
property: 'price' ,
order: 'ASC'
}
})
For vector search, sorting overrides the default similarity-based ranking.
Hybrid Search
const results = search ( db , {
mode: 'hybrid' ,
term: 'headphones' ,
vector: {
value: embeddings ,
property: 'embedding'
},
sortBy: {
property: 'price' ,
order: 'ASC'
}
})
Combining Sorting with Filters
Filter results first, then sort:
const results = search ( db , {
term: 'headphones' ,
where: {
price: {
lt: 100
},
inStock: true
},
sortBy: {
property: 'rating' ,
order: 'DESC'
}
})
Sorting is applied after filtering, so only filtered results are sorted.
Combine sorting with limit and offset:
const results = search ( db , {
term: 'headphones' ,
sortBy: {
property: 'price' ,
order: 'ASC'
},
limit: 10 ,
offset: 0
})
// Next page
const nextPage = search ( db , {
term: 'headphones' ,
sortBy: {
property: 'price' ,
order: 'ASC'
},
limit: 10 ,
offset: 10
})
Disabling Sortable Properties
You can disable sorting on specific properties using sorter configuration:
import { create } from '@orama/orama'
const db = create ({
schema: {
title: 'string' ,
description: 'string' ,
price: 'number'
},
components: {
sorter: {
unsortableProperties: [ 'description' ]
}
}
})
// This will work
search ( db , {
term: 'product' ,
sortBy: { property: 'price' , order: 'ASC' }
})
// This will throw an error
search ( db , {
term: 'product' ,
sortBy: { property: 'description' , order: 'ASC' }
})
Attempting to sort by an unsortable property will throw an error.
Index Sorted Properties
Properties used for sorting are automatically indexed during document insertion
Limit Result Count
Use limit to reduce the number of results that need sorting: search ( db , {
term: 'query' ,
sortBy: { property: 'price' , order: 'ASC' },
limit: 20 // Only sort top 20 results
})
Simple Sorting is Faster
Single-property sorting is faster than custom sort functions: // Faster
sortBy : { property : 'price' , order : 'ASC' }
// Slower (but more flexible)
sortBy : ( a , b ) => { /* complex logic */ }
Consider Relevance Scoring
For text search, the default relevance sorting is often the best choice
Common Use Cases
E-commerce Sort products by price, rating, or popularity
Content Sorting Sort articles by date, views, or relevance
Leaderboards Sort users by score or ranking
Inventory Sort items by stock level or location
Filters Filter before sorting
Full-Text Search Combine sorting with text search
Boosting Influence relevance scoring before sorting