How to Use Field Filters in Hister Queries: url, title, and type Explained

Field filters in Hister use the syntax field:value—such as url:github.com, title:"Release Notes", or type:pdf—to restrict searches to specific metadata columns, supporting wildcards (*), quoted phrases for whitespace, and case‑insensitive matching.

Hister is an open‑source browsing history search engine written in Go that indexes URLs, titles, and content type. Understanding how to use field filters in Hister queries lets you bypass full‑text noise and target exact attributes of a document. The implementation follows a strict parsing pipeline defined in the asciimoo/hister repository.

Built‑in Field Filters

Hister exposes three primary field filters that map directly to indexed document metadata. Each accepts a value that may contain wildcards or be wrapped in double quotes to preserve spaces.

The url: Filter

The url: filter targets the document’s complete address, including protocol, host, and path. It is useful for narrowing results to a specific domain or directory pattern.

  • Syntax: url:pattern
  • Example: url:stackoverflow.com matches any URL containing that domain.
  • Wildcard: url:*github.com/readme* matches paths containing “readme” anywhere inside a GitHub domain.

The title: Filter

The title: filter searches the page title string extracted during indexing. Because titles often contain spaces, values should be quoted when matching phrases.

  • Syntax: title:"exact phrase" or title:word
  • Example: title:"Free Software" returns documents whose title includes that exact two‑word sequence.
  • Case handling: Comparisons are case‑insensitive.

The type: Filter

The type: filter restricts results by document classification, such as page, pdf, or image. This allows you to isolate binary formats from standard HTML pages.

  • Syntax: type:category
  • Example: type:pdf returns only PDF documents present in the index.

How Hister Parses Field Filters

Internally, Hister converts a raw query string into a Bleve search query. In server/indexer/querybuilder/builder.go, the parser scans for the colon delimiter to separate field identifiers from their values, generating structured filter nodes at lines 30‑31. This stage distinguishes field constraints from free‑text keywords before the query is executed.

Applying Filters to History Items

After parsing, the constraints are applied to the underlying data store. The function filteredHistoryItems in server/model/history.go (lines 228‑235) translates the parsed filters into GORM query conditions, ensuring that only history rows matching all specified field criteria are returned. This function is the bridge between the Bleve query layer and the SQLite backing store.

Search Schema Definition

The fields available for filtering are declared in server/indexer/searchschema/schema.go. This schema explicitly marks url, title, and type as indexed, filterable columns, allowing the Bleve indexer to build the appropriate term dictionaries for fast lookups.

Practical Query Examples

The following snippets demonstrate how to submit field‑filtered queries via the CLI, Go SDK, and Web UI.


# 1. Search only URLs that contain "stackoverflow.com"

hister search "url:stackoverflow.com"

# 2. Find documents whose title mentions "hister" but only PDFs

hister search "title:hister type:pdf"

# 3. Combine a URL filter with a free-text term

hister search "go concurrency url:*github.com*"
// Using the Go client – field filters are passed as part of the query string
// (the client forwards the string unchanged to the server)
query := "title:\"Free Software\" type:pdf"
results, err := client.Search(context.Background(), query)
if err != nil { log.Fatal(err) }
fmt.Printf("Found %d PDF docs with title containing “Free Software”\n", len(results.Documents))
/* Web UI – building a query with field filters */
const query = `url:${userInputUrl} title:"${userInputTitle}"`;
apiFetch('/api/search', { method: 'POST', body: JSON.stringify({ query }) })
  .then(r => r.json())
  .then(data => displayResults(data.documents));

Summary

  • Syntax: Use field:value where field is one of url, title, or type.
  • Wildcards: Asterisks (*) act as通配符 inside any filter value.
  • Quoting: Wrap multi‑word values in double quotes to preserve spacing (e.g., title:"Quick Start").
  • Implementation: Parsing happens in server/indexer/querybuilder/builder.go, filtering logic resides in server/model/history.go, and the schema is defined in server/indexer/searchschema/schema.go.
  • Combination: Multiple field filters can be joined in a single query; Hister returns the intersection of all constraints.

Frequently Asked Questions

Are field filters case‑sensitive?

No. Hister normalizes both the indexed values and the query input to the same casing during comparison, so url:GITHUB.COM and url:github.com return identical results.

Can I combine multiple field filters in one query?

Yes. Separate each field:value pair with a space. Hister applies boolean AND logic, meaning every document in the result set must satisfy all provided filters simultaneously (e.g., title:roadmap type:pdf url:*asciimoo*).

How do I search for a value that contains spaces?

Wrap the value in double quotes immediately following the colon: title:"Meeting Notes". Without quotes, everything after the first space is treated as a separate keyword or filter.

What document types are recognized by the type: filter?

The filter accepts any MIME type category that Hister indexed during ingestion, commonly including page (HTML), pdf, and image. The exact set depends on the content present in your local history database.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →