# How to Configure Sorting Options in Hister Search Results

> Learn to configure sorting options in Hister search results using query directives, CLI flags, or API parameters. Master your search schema for efficient results.

- Repository: [Adam Tauber/hister](https://github.com/asciimoo/hister)
- Tags: how-to-guide
- Published: 2026-08-27

---

**You can configure sorting options in Hister by using the `sort:` query directive (e.g., `sort:date`), the `--sort` CLI flag, or the sort parameter in API calls, with all available options defined centrally in the search schema.**

Hister is an open-source search engine that provides flexible result ordering through a centralized sorting configuration. The repository `asciimoo/hister` implements a **sorting system** that allows users to reorder search results by relevance, date, visit count, or domain across multiple interfaces including the CLI, HTTP API, and MCP tool-calling interface.

## Understanding the Sort Schema

The canonical definition of available sorting strategies lives in [`server/indexer/searchschema/schema.go`](https://github.com/asciimoo/hister/blob/main/server/indexer/searchschema/schema.go). This file contains the `sortCapabilities` variable (lines 162‑176), which declares an array of `SortDefinition` structs that map user-facing labels to low-level Bleve search keys.

Each `SortDefinition` contains:
- **Value** – The token users specify (e.g., `date`, `visits`)
- **Fields** – The Bleve sort field sequence (e.g., `["-updated", "_id"]`)
- **ByScore** – A boolean flag indicating whether the sort relies on relevance scores
- **Default** – Whether this option is the fallback when no sort is specified

The schema exposes these definitions through helper functions `LookupSort`, `Sort`, and `CapabilitiesDefinition` (lines 263‑271), which the query builder and indexer consume to validate and apply sorting directives.

## Available Sort Options

Hister ships with eight built-in sorting strategies defined in the schema:

- **Relevance** (`relevance`) – Default sort using `["-_score", "-updated", "_id"]` with `ByScore: true`
- **Least relevant** (`-relevance`) – Ascending relevance score
- **Most visited** (`visits`) – Descending visit count (`add_count`)
- **Least visited** (`-visits`) – Ascending visit count
- **Date (newest first)** (`date`) – Descending update timestamp
- **Date (oldest first)** (`-date`) – Ascending update timestamp
- **Domain (A to Z)** (`domain`) – Alphabetical by domain
- **Domain (Z to A)** (`-domain`) – Reverse alphabetical by domain

## Using Sort Parameters

Hister exposes sorting controls through three primary interfaces, all backed by the same schema definitions.

### Query String Syntax

When performing a search, append the `sort:` directive followed by any valid sort value:

```bash
my search term sort:date

```

The query builder in [`server/indexer/querybuilder/search.go`](https://github.com/asciimoo/hister/blob/main/server/indexer/querybuilder/search.go) (lines 47‑64) extracts this token using the `sortDirective` function, validates it against the schema via `LookupSort`, and strips the default `relevance` placeholder to ensure the final query object contains only effective sort strings.

### CLI Configuration

The `search` command in [`cmd/search.go`](https://github.com/asciimoo/hister/blob/main/cmd/search.go) (lines 63‑70) accepts a `--sort` flag that validates input against the known values before forwarding the request to the server:

```bash
hister search --sort=visits "machine learning"

```

Available CLI values include `relevance`, `date`, `domain`, and `visits`. Invalid selections trigger an error before the network request occurs.

### API and MCP Interface

For programmatic access, the MCP tool description in [`server/mcp.go`](https://github.com/asciimoo/hister/blob/main/server/mcp.go) (lines 79‑84) autogenerates a JSON schema listing all visible sort options from the schema's `CapabilitiesDefinition`. This allows AI assistants and API consumers to discover available sorts dynamically without hardcoding values.

## How Sorting Works Internally

When the `Indexer.Search` method processes a query, it retrieves the appropriate `SortDefinition` via `searchschema.Sort(q.Sort)` and applies the field list to the underlying Bleve request:

```go
// server/indexer/indexer.go lines 1649-1651
sortDefinition := searchschema.Sort(q.Sort)
sortByScore := sortDefinition.ByScore
req.SortBy(sortDefinition.Fields)

```

If the sort uses relevance scores (`ByScore == true`), the pagination logic later rewrites the `_score` placeholder with actual document scores (lines 1689‑1696). This ensures that paginated results maintain consistent ordering even as score values materialize during query execution.

## Extending Sort Options

To add a custom sorting strategy to Hister:

1. **Define the sort** in [`server/indexer/searchschema/schema.go`](https://github.com/asciimoo/hister/blob/main/server/indexer/searchschema/schema.go) by appending a new `SortDefinition` to `sortCapabilities.Options` with the appropriate `Fields` array pointing to your Bleve index fields.

2. **Update visibility** by setting `Visible: true` if the option should appear in CLI help text and MCP descriptions.

3. **Run tests** using `go test ./...` to verify integration. Existing test cases such as `TestSortFallsBackToDefault` and `TestSearchSortDirective` validate that new options integrate correctly with the query parser and indexer.

## Summary

- Hister defines sorting strategies centrally in [`server/indexer/searchschema/schema.go`](https://github.com/asciimoo/hister/blob/main/server/indexer/searchschema/schema.go) using the `SortDefinition` struct.
- Users can specify sorts via the `sort:` query directive (e.g., `sort:date`), the `--sort` CLI flag, or API parameters.
- Available options include relevance, date, visits, and domain, each supporting ascending and descending variants.
- The `ByScore` flag in the schema enables proper pagination for relevance-based sorting by replacing the `_score` placeholder with actual values.
- Custom sorts require adding entries to the schema and ensuring underlying Bleve fields exist in the index.

## Frequently Asked Questions

### What is the default sort order in Hister?

By default, Hister sorts results by **relevance** in descending order. This is defined in [`server/indexer/searchschema/schema.go`](https://github.com/asciimoo/hister/blob/main/server/indexer/searchschema/schema.go) where the `relevance` entry has `Default: true` and uses the field sequence `["-_score", "-updated", "_id"]`. When no sort directive is provided, the system automatically falls back to this definition.

### Can I sort by custom metadata fields in Hister?

Yes, but you must first extend the search schema. Add a new `SortDefinition` to `sortCapabilities.Options` in [`server/indexer/searchschema/schema.go`](https://github.com/asciimoo/hister/blob/main/server/indexer/searchschema/schema.go) referencing your custom Bleve field name in the `Fields` array. After reindexing your data with the new field, the sort option becomes available through all interfaces (CLI, API, and MCP).

### How does Hister handle score-based pagination?

When a sort uses relevance scores (`ByScore: true`), the indexer in [`server/indexer/indexer.go`](https://github.com/asciimoo/hister/blob/main/server/indexer/indexer.go) (lines 1689‑1696) replaces the `_score` placeholder in the sort definition with the actual document score during result processing. This allows the system to maintain stable pagination across requests, even though Bleve computes scores at query time rather than index time.

### Where can I find the list of available sort options programmatically?

Call the `CapabilitiesDefinition()` function from [`server/indexer/searchschema/schema.go`](https://github.com/asciimoo/hister/blob/main/server/indexer/searchschema/schema.go) or query the MCP tool description generated in [`server/mcp.go`](https://github.com/asciimoo/hister/blob/main/server/mcp.go) (lines 79‑84). Both sources read from the central `sortCapabilities` variable and return the current set of visible sort options, ensuring your client stays synchronized with the server configuration.