Skip to content

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.

1. Prerequisites

  • Go 1.27 or newer
  • Node.js and npm, for the admin UI that just build embeds
  • just
  • zsh

Start from the root of a ysearch source checkout (git.teixos.net/moltavista/ysearch). All commands below run from there.

2. Build the binaries

zsh
just build

This 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.

3. Start the server

zsh
./bin/ysearch-local

It 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/models

The 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.

4. Declare a schema

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:

zsh
./bin/ysearch schema apply deploy/swarm/articles.proto

apply 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:

protobuf
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.

5. Load documents

zsh
./bin/ysearch push articles deploy/swarm/articles.jsonl

push 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.7s

The input is JSONL: one JSON object per line whose member names are the schema's field names.

6. Run a query

zsh
./bin/ysearch search articles 'title:search' --fields title,url

The 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 storage

A 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:

zsh
./bin/ysearch search articles '[word="cold"] []{0,3} [word="cache"]' \
  --dialect cqp --fields title,url

explain shows the syntax tree, the lowered query, and its canonical digest:

zsh
./bin/ysearch explain 'title:search AND +body:cache' --index articles

The Lucene and CQP guides cover both grammars, and filters covers --filter.

7. Output shapes

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
zsh
./bin/ysearch search articles search --ids --top-k 100

--ids is the cheapest large-result path.

8. Statistics and the console

zsh
./bin/ysearch stats articles

The 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.

9. Stop and clean up

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:

zsh
local_root="$(realpath ./ysearch-local-data)"
test "$local_root" = "$(pwd -P)/ysearch-local-data" && rm -rf -- "$local_root"

Where to go next

  • 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