Skip to content
Arbinel

Search

Arbinel adds a Typesense backend for issue search and limits zoekt code search. Everything else about the indexers works as in Forgejo, and the Forgejo configuration cheat sheet describes the [indexer] settings.

Typesense is an open source search server that can replicate across several nodes without a paid edition. Compared with the meilisearch backend, the typesense backend:

  • reports exact result counts, where Meilisearch reports an estimate,
  • finds issue 13 when you search for #13, ranking the issue number above title and text matches.
[indexer]
ISSUE_INDEXER_TYPE = typesense
ISSUE_INDEXER_CONN_STR = http://API_KEY@typesense.internal:8108
Key Default Meaning
ISSUE_INDEXER_TYPE bleve Set to typesense.
ISSUE_INDEXER_CONN_STR empty URL of the Typesense server, with the API key as the user name.
ISSUE_INDEXER_NAME gitea_issues Base name of the Typesense collection.

The connection string must start with http:// or https://, and Arbinel refuses to start with a bare host:8108. Arbinel reads the API key from the user information in the URL. It uses the password if there is one, and otherwise the user name. Both http://API_KEY@host:8108 and http://user:API_KEY@host:8108 work, and Arbinel does not use ISSUE_INDEXER_CONN_AUTH. Instead of ISSUE_INDEXER_CONN_STR, you can also set Forgejo’s ISSUE_INDEXER_PROTOCOL, ISSUE_INDEXER_HOST, ISSUE_INDEXER_USER and ISSUE_INDEXER_PASSWD.

Each call to Typesense times out after 10 seconds.

Arbinel stores issues in a collection named after ISSUE_INDEXER_NAME with a schema version appended, gitea_issues_v1 by default. At startup, if the collection does not exist, Arbinel creates it and indexes every issue and pull request from the database.

To rebuild the index, delete the collection and restart Arbinel:

curl -X DELETE -H "X-TYPESENSE-API-KEY: API_KEY" \
  http://typesense.internal:8108/collections/gitea_issues_v1

Arbinel can always rebuild the index from the database, so you do not need to back up Typesense. If a later Arbinel release changes the schema, it uses a new collection name, and Arbinel rebuilds the index automatically.

To switch from Meilisearch, change ISSUE_INDEXER_TYPE and restart. Arbinel does not delete the Meilisearch index, so you can switch back immediately.

  • If Typesense cannot be reached, keyword searches fail and the issue list shows “Searching by keyword is currently not available”. Lists without a keyword still work, because they come from the database. The cause is logged as Issue indexer unavailable.
  • If Typesense loses the collection while Arbinel runs, for example after a restart without a persistent volume, every keyword search fails with Collection not found until Arbinel restarts and rebuilds it. Give Typesense a persistent volume.
  • Every word in the query must match.
  • The last word also matches as a prefix, so auth finds “authentication”.
  • Typesense tolerates up to two typos per word.
  • "quoted phrases" match as a phrase, and -word excludes a word.

These rules are fixed in the code and cannot be configured.

Forgejo can use zoekt for code search with REPO_INDEXER_TYPE = zoekt. Arbinel limits each search. In Forgejo, one broad query can load every matching file into memory before Forgejo renders the first page of results.

Limit Value
Time per search 2 seconds
Files returned 1,000
Matches per shard 100,000
Matches in total 1,000,000

These limits cannot be configured. A search that matches more files shows a result count of at most 1,000, and you cannot page beyond those results. Code search can also be limited per account with the code-search request budget.

zoekt adds a new index shard for every push and never merges them. Arbinel rebuilds a repository’s index once it has more than 64 shards, at the repository’s next push. In high availability mode, each node also does this for idle repositories once an hour.

On several nodes, each node keeps its own zoekt index on a local disk. Code search on several nodes explains how the nodes keep their indexes up to date.