Prompt
How do I support sorting in embedded search?
Latest observation
To support sorting in embedded search, you generally want to make sorting a first-class part of your search query and result pipeline, not something bolted on afterward.
Core idea
Your embedded search should:
- Accept a sort specification
- e.g.
sort=price asc,sort=createdAt desc
- e.g.
- Map that sort to fields available in your indexed data
- Only sort on fields that are stored in a sortable form
- Apply sorting before pagination
- Sort first, then take the page slice
- Return the sort metadata with results
- So the client knows what order it is seeing
Typical implementation steps
1) Define sortable fields
Not every field should be sortable. Choose fields like:
titlecreatedAtupdatedAtpriceratingrelevance(default search order)
If you’re using a search index, these fields often need to be indexed as:
- keyword / exact values for strings
- numeric types for numbers
- date types for timestamps
2) Extend the search API
Add parameters like:
sortBy=createdAtsortDir=desc
Or a single parameter:
sort=createdAt:desc
Example:
GET /search?q=shoes&sort=price:asc
3) Validate sort input
Never allow arbitrary field sorting without validation. Use a whitelist:
const sortableFields = ['createdAt', 'price', 'rating', 'title'];
if (!sortableFields.includes(sortBy)) {
throw new Error('Unsupported sort field');
}
This prevents errors and avoids exposing sensitive/internal fields.
4) Apply sorting in the data layer
How you do this depends on where your search happens:
If using a database query
Example SQL:
SELECT *
FROM products
WHERE name ILIKE '%shoes%'
ORDER BY price ASC
LIMIT 20 OFFSET 0;
If using Elasticsearch/OpenSearch
Use the sort clause:
{
"query": {
"match": {
"name": "shoes"
}
},
"sort": [
{ "price": "asc" }
]
}
If using a custom in-memory search
Sort the result array before slicing:
results.sort((a, b) => a.price - b.price);
const page = results.slice(offset, offset + limit);
5) Keep relevance sorting as default
For full-text embedded search, the default sort is usually relevance. Let users override it with field-based sorting when needed.
Common pattern:
- Default: relevance
- Optional: sort by a field
- Sometimes: combine relevance + secondary sort
Example:
- First by score
- Then by
createdAt descto break ties
Important considerations
Multi-field sorting
Sometimes you want:
sort=category asc,price asc
That means:
- Group by category
- Sort within category by price
Null handling
Decide how null values behave:
- Put nulls first
- Put nulls last
- Exclude nulls from sortable fields
Example SQL:
ORDER BY price ASC NULLS LAST
Stability
If many records have the same sort value, add a tiebreaker:
ORDER BY price ASC, id ASC
This keeps pagination consistent.
Performance
Sorting can be expensive on large datasets if the field isn’t indexed properly. Make sure:
- the field is indexed
- the field type matches the sort need
- pagination is efficient
Good UX pattern
In embedded search UIs, expose sorting as:
- a dropdown: “Relevance”, “Newest”, “Price: Low to High”
- clear default order
- persist chosen sort across pages
Recommended API shape
{
"query": "shoes",
"sort": {
"field": "price",
"direction": "asc"
},
"page": 1,
"pageSize": 20
}
Or:
{
"query": "shoes",
"sort": "price:asc"
}
If you want, I can also show:
- a SQL example,
- an Elasticsearch/OpenSearch example, or
- a frontend + backend design for embedded search sorting.
Brands