Which documents hold this word? Semurg as a search index, and how far it goes today
12 October 2026 · Semurg · 3 min read · Markdown
Verified: every command below ran on a fresh node of r11.78.20261012.bc0d94f (how)
Search here means the plainest question a search index answers: which documents contain this word, and how many. Semurg keeps, for every word, a small record of how many documents hold it, and an append-only list of which ones, so counting a word is one read and listing its documents is one sweep. It does not rank results yet, and this post says so before you invest in it.
Index documents
Send each document's text under your own whole-number id. Run this once: indexing the same document again counts it twice.
export SEMURG_API_TOKEN=<your token>
curl -sS http://localhost:4000/v1/query \
-H "Authorization: Bearer $SEMURG_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"op": "index_documents",
"docs": [{"id": 900000000601, "body": "invoice export drops the currency column"},
{"id": 900000000602, "body": "the currency selector resets after login"},
{"id": 900000000603, "body": "export to spreadsheet is slow"}]}'Expected: three documents indexed
Words are runs of the letters a to z and the digits; anything else separates words, and there is no stemming, so export and exports are different words.
Count and list
term_docs counts the documents holding each of a list of words in one call; term_postings lists the documents holding one word, in ascending id order:
export SEMURG_API_TOKEN=<your token>
curl -sS http://localhost:4000/v1/query \
-H "Authorization: Bearer $SEMURG_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"op": "term_postings", "word": "currency"}'Expected: the two documents that mention currency
To find documents holding two words, list each word's documents and keep the ids both lists share. To change a document, delete it with the text it was indexed with, then index the new text; delete_documents takes the same shape as index_documents.
Where it stands
We have taken our published benchmark rows down while every domain is re-measured on new hardware, with a dataset in RAM and one bigger than RAM running at the same time, as a stress test of Semurg itself. The re-measured search results will be on the benchmark page, wins and losses alike, with the release and the machine they ran on. Until then this post states no comparison.
What it does not do yet
- Rank results by relevance: a word's documents come back in id order.
- Phrases, AND, OR or NOT in one query: combine word lists in your own code.
- Words with letters outside a to z, or stemming.
- Delete a document without sending the text it was indexed with; and indexing the same document twice counts it twice.
- Import from another search engine, such as OpenSearch.
Next
- Four kinds of data, one route: search beside objects, streams and places.
- Nearest vectors, filtered, then walked: a word as a filter on a vector search.
How these commands were checked
Our test farm ran each of the 2 command blocks marked runnable, exactly as written, with the answer checked against the expectation printed under it, against a fresh node of the published release r11.78.20261012.bc0d94f. A post is published only when every one of them passed there.