Start
Quick start
Build the tools, start a local server, apply a schema, load documents, and run a query with the engine on ysearch main today.
This page gets you from a source checkout to a served query. It uses
ysearch-local: one OS process that runs the complete data plane of the
inherited search engine plus the admin UI, with no flags and no object store
to set up. The sample schema and documents are already in the repository.
Everything here runs on your own machine and writes to one directory you can delete afterward.
- Go 1.27 or newer
- Node.js and npm, for the admin UI that
just buildembeds just- zsh
Start from the root of a ysearch source checkout
(git.teixos.net/moltavista/ysearch). All commands below run from there.
just buildThis compiles everything under ./cmd/... and ./tools/... into ./bin,
which is gitignored. You need two of the results: ysearch-local, the
single-process server, and ysearch, the client.
./bin/ysearch-localIt prints a ready block and stays in the foreground:
ysearch-local: ready
data: 127.0.0.1:9500
admin: http://127.0.0.1:8787
root: <cwd>/ysearch-local-data
objects: <cwd>/ysearch-local-data/objects
cache: <cwd>/ysearch-local-data/cache
ingest: <cwd>/ysearch-local-data/ingest
models: <cwd>/ysearch-local-data/modelsThe four directories are the whole installation: objects/ holds the
authoritative schemas, segments, commit markers, and catalogs; cache/ is
disposable; ingest/ is the durable spool and build scratch; models/ holds
checksum-addressed embedding model packages. Data persists across restarts.
Leave this terminal running and open a second one for the rest of the steps.
A schema is a protobuf message. Field numbers are the field IDs the index keeps forever, and options on the message and its fields say what the index does with each one. The repository ships one:
./bin/ysearch schema apply deploy/swarm/articles.protoapply compiles the .proto in-process, with no protoc or buf, and
prints one line naming the result:
schema articles: created v1 (message dev.Article, 6 fields: 2 indexed, 6 stored, 4 filterable, key: url)The file declares an articles index whose url field is the logical key and
whose title and body are indexed:
message Article {
option (ysearch.v1.document) = {index: "articles"};
string url = 1 [(ysearch.v1.field) = {key: true}];
string title = 2 [(ysearch.v1.field) = {
indexed: true
stored: true
weight: 2.0
b: 0.6
}];
string body = 3 [(ysearch.v1.field) = {
indexed: true
stored: true
}];
string site = 4;
string category = 5;
google.protobuf.Timestamp published = 6;
}Applying the first schema creates the index. Schemas covers every option.
./bin/ysearch push articles deploy/swarm/articles.jsonlpush fetches the schema, validates each document client-side, and streams
batches to the server. By default the last batch carries a flush, so push
returns only once the segment is published and served by this process. The
segment ID, generation ID, and time differ on every run:
pushed 6 documents in 1 batches · sealed segment 01a0d955… · generation b13dda96… · PUBLISHED in 2.7sThe input is JSONL: one JSON object per line whose member names are the schema's field names.
./bin/ysearch search articles 'title:search' --fields title,urlThe table prints KEY, SCORE, VERSION, then one column per projected
field. For the sample documents, two articles match (columns abridged):
KEY SCORE title
https://example.test/search/distributed 1.4048 Distributed search with two workers
https://example.test/search/object-storage 1.4048 Search engines on object storageA space between terms means OR. To require both, write AND or put + in
front of each clause. Terms are not stemmed: body:cache does not match
"caches".
CQP is the positional grammar. []{0,3} is a gap of up to three tokens:
./bin/ysearch search articles '[word="cold"] []{0,3} [word="cache"]' \
--dialect cqp --fields title,urlexplain shows the syntax tree, the lowered query, and its canonical digest:
./bin/ysearch explain 'title:search AND +body:cache' --index articlesThe Lucene and CQP guides cover both
grammars, and filters covers --filter.
The output format decides what the server has to read:
| Flag | Prints | Server reads |
|---|---|---|
--fields a,b |
a table with projected values | stored records for every ranked hit |
--keys |
one logical key per line | stored records and mutation-version blocks |
--ids |
one 32-character hex public ID per line | neither stored records nor scores |
./bin/ysearch search articles search --ids --top-k 100--ids is the cheapest large-result path.
./bin/ysearch stats articlesThe table names the generation, the segment count, the document count, and
the scorer. ysearch-local scores with bm25f-v1; the pinned-statistics
scorer bm25f-pinned-v1 of YS2 runs only in the catalog-following query roles
of ysearch node (see the guides).
Then open http://127.0.0.1:8787. The admin console shows schemas and node statistics, runs queries, applies schemas, and uploads documents.
Ctrl-C in the first terminal drains both endpoints and stops the process.
Restarting ./bin/ysearch-local reopens the same schemas and documents. To
delete the local database instead, stop the process and run this guarded reset
from the repository root:
local_root="$(realpath ./ysearch-local-data)"
test "$local_root" = "$(pwd -P)/ysearch-local-data" && rm -rf -- "$local_root"- Local development: the swarm stack with real process boundaries, MinIO, Redpanda, and the marekvs sidecar
- Ingest: batching, sealing, flush semantics, and deletes
- Vectors: embedding profiles and hybrid search
- Architecture: where ysearch is going
- CLI reference: every command and flag