How it works
memista pairs two well-known pieces — USearch for the index and SQLite for the metadata — and keeps them in sync with a shared chunk id. An Actix-web layer exposes three endpoints on top.
┌─────────────────────────────────────────────────────────┐
│ POST /v1/insert POST /v1/search DELETE /v1/drop │
│ (actix-web + apistos OpenAPI) │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌─────────────────────┐ │
│ │ SQLite (WAL) │◀───────▶│ USearch index │ │
│ │ chunks_<db_id> │ chunk │ <db_id>.usearch │ │
│ │ (text, metadata) │ id │ HNSW · IP · f32 │ │
│ └──────────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘ The insert path
On POST /v1/insert, the row (text + metadata) is written to the SQLite table
chunks_<database_id> first. The returned chunk_id becomes the
USearch key for the vector. Because the SQLite id and the USearch key are the
same integer, the two stores never drift. After the batch, the
<database_id>.usearch index file is saved to disk.
The search path
On POST /v1/search, USearch returns ranked keys for the query vector, ordered by
inner-product distance (MetricKind::IP, F32). memista then
hydrates the text and metadata for those keys back from SQLite and returns them with their
distances. One index lookup, one metadata read.
Partitions
Each database_id is a partition: its own SQLite table and its own
.usearch file. Isolation is by name. DELETE /v1/drop removes both.
See persistence and the .usearch file.
Defaults you can tune
The stock build passes USearch's default connectivity,
expansion_add, and expansion_search (all 0, meaning
"use USearch defaults"). To trade recall against latency, fork the
load_or_create_index helper. Embedding dimensions are likewise fixed at index
creation — see changing embedding dimensions.