moonrag 0.1

reference

Every public name, in one place

Generated from each package's interface file and the doc comments in its sources, so this page cannot describe a library that is not there — and cannot leave a public name out.

moonrag

Documents, the five contracts, the in-memory store, the retrievers, vector arithmetic and metadata filters.

suberrorRefused

A request the library will not carry out. Mismatch is two vectors of different length meeting where one length is needed, Empty a blank string where one has to be non-blank, Exceeded a number outside the range limit bounds, Malformed unreadable input at at, and Unsupported a request this build does not serve.

pub(all) suberror Refused {
  Mismatch(got~ : Int32, want~ : Int32)
  Empty(what~ : String)
  Exceeded(limit~ : Int32, got~ : Int32)
  Malformed(at~ : Int32, why~ : String)
  Unsupported(what~ : String)
}

structCandidate

A document together with the vector it was embedded to. MMR reranks by comparing candidates with each other, and a score alone cannot do that: the vectors have to travel with the documents.

pub(all) struct Candidate {
  document : Document
  vector : Array[Double]
}

structDocument

A piece of text, with an optional identity and metadata. id is what a store keys a document by. Leave it None and the store assigns one; set it and the document keeps the same identity across re-indexing, which is what makes an update replace the old copy instead of piling up beside it. meta carries whatever the caller needs — a source path, a page number, a heading path — and is what a Filter reads.

pub(all) struct Document {
  id : String?
  text : String
  meta : Map[String, @json.Json]
}
pub fn Document::derived(Self, Int32, String, start_index? : Int32) -> Self

A document cut out of parent: same metadata plus the chunk number, a derived id when the parent had one, and the offset it started at when the splitter knows it. Splitters are not the only producers of chunks — a caller streaming pages out of a PDF has the same needs — so the bookkeeping lives here rather than in each of them.

pub fn Document::from_json(@json.Json, @json.JsonPath) -> Self raise @json.JsonDecodeError
pub fn Document::meta_of(Self, String) -> @json.Json?

The metadata value stored under key, or None.

pub fn Document::new(String, id? : String, meta? : Map[String, @json.Json]) -> Self

A document with text, no identity, and no metadata.

pub fn Document::set_meta(Self, String, @json.Json) -> Self

The same document with key set to value; a key already present is replaced.

pub fn Document::str_meta(Self, String) -> String?

The metadata value stored under key when it is a string, or None.

pub fn Document::to_json(Self) -> @json.Json
pub fn Document::with_id(Self, String) -> Self

The same document under id, for a store that keys by caller-chosen identity.

pub fn Document::with_meta(Self, Map[String, @json.Json]) -> Self

The same document carrying metadata, for a filter to match on.

enumFilter

A condition on a document's metadata. Equal matches a whole JSON value, OneOf any of a list, Exists only that the key is present, and Compare a number against an operand. All and Any nest, Not negates. A document whose metadata lacks the key matches nothing except Not of a filter it would otherwise fail.

pub(all) enum Filter {
  Equal(String, @json.Json)
  OneOf(String, Array[@json.Json])
  Exists(String)
  Compare(String, Order, Double)
  All(Array[Filter])
  Any(Array[Filter])
  Not(Filter)
}
pub fn Filter::matches(Self, Document) -> Bool

Whether document satisfies the filter.

structHashingEmbedder

A deterministic embedder that needs neither a model nor a network: it hashes the words and the character trigrams of a text into a fixed-width vector. It is lexical, not semantic — "cat" and "feline" land far apart — so it suits tests, offline examples and keyword-ish retrieval, not production ranking. Being deterministic, it is also the vector source for differential tests: the same text yields the same vector on every target.

pub struct HashingEmbedder {
  dimension : Int32
}
pub async fn HashingEmbedder::embed(Self, ArrayView[String]) -> Array[Array[Double]]
pub fn HashingEmbedder::new(dimension? : Int32) -> Self raise

A hashing embedder producing dimension-component vectors. 256 is wide enough that a handful of documents rarely collide and narrow enough to keep a fixture readable. Raises Empty when dimension is not positive.

structInMemoryVectorStore

A VectorStore held in memory, keyed by document id. The store embeds what it is given, so add takes documents while a search takes the query's vector. That split is deliberate: writing is the rare, batched, cacheable path, while a search often reuses one query vector across several stores.

pub struct InMemoryVectorStore {
  embedder : &Embedder
  mut entries : Array[(String, Document, Array[Double])]
  mut counter : Int32
}
pub async fn InMemoryVectorStore::add(Self, Array[Document]) -> Array[String]
pub fn InMemoryVectorStore::add_vectors(Self, Array[Document], ArrayView[Array[Double]]) -> Array[String] raise

Store documents that already carry their vectors, returning their ids. An id already present is replaced in place, which is what makes a re-index an update rather than a duplicate. Raises Mismatch when the vector count differs from the document count or two vectors differ in length, and Empty for a document whose id is the empty string.

pub fn InMemoryVectorStore::clear(Self) -> Unit

Remove every stored document.

pub async fn InMemoryVectorStore::delete(Self, ArrayView[String]) -> Unit
pub fn InMemoryVectorStore::get(Self, String) -> Document?

The document stored under id, or None. The returned document carries the id it is stored under, so it can be deleted or refetched without keeping the id beside it.

pub fn InMemoryVectorStore::ids(Self) -> Array[String]

The ids of the stored documents, in the order they were added.

pub fn InMemoryVectorStore::len(Self) -> Int32

The number of stored documents.

pub fn InMemoryVectorStore::new(&Embedder) -> Self

An empty store that embeds with embedder.

pub fn InMemoryVectorStore::vector_of(Self, String) -> Array[Double]?

The vector stored for id, or None — for a caller that reranks hits itself.

structMmrRetriever

Returns relevant documents that are also unlike each other, by maximal marginal relevance. A plain search on a corpus of near-duplicates returns the same paragraph five times. MMR trades some relevance for coverage: lambda near 1 behaves like a plain search, near 0 like "the most different thing that is still related".

pub struct MmrRetriever {
  embedder : &Embedder
  store : &VectorStore
  filter : Filter?
  lambda : Double
  fetch_limit : Int32
}
pub fn MmrRetriever::new(&Embedder, &VectorStore, lambda? : Double, fetch_limit? : Int32, filter? : Filter) -> Self

An MMR retriever over store. fetch_limit candidates are ranked by similarity first and then reranked by MMR, so it must be at least the limit a caller asks for; lambda weights relevance against diversity.

pub async fn MmrRetriever::retrieve(Self, String, limit~ : Int32) -> Array[Scored]

enumOrder

How Compare orders a metadata number against its operand.

pub(all) enum Order {
  Less
  AtMost
  AtLeast
  Greater
}

structScored

A document and the score it earned: what one search returns.

pub(all) struct Scored {
  document : Document
  score : Double
}
pub fn Scored::documents(ArrayView[Self]) -> Array[Document]

The documents in hits, dropping the scores.

pub fn Scored::from_json(@json.Json, @json.JsonPath) -> Self raise @json.JsonDecodeError
pub fn Scored::to_json(Self) -> @json.Json

structSimilarityRetriever

Ranks documents by cosine similarity to the query, and returns the best limit.

pub struct SimilarityRetriever {
  embedder : &Embedder
  store : &VectorStore
  filter : Filter?
}
pub fn SimilarityRetriever::new(&Embedder, &VectorStore, filter? : Filter) -> Self

A similarity retriever over store, embedding queries with embedder. filter narrows the candidates before ranking, in the store where the documents live.

pub async fn SimilarityRetriever::retrieve(Self, String, limit~ : Int32) -> Array[Scored]

traitEmbedder

Turns batches of text into vectors of equal length. One call embeds a batch, not a string: every model worth calling charges per request, and a batch is also what makes a re-index affordable. All vectors in a batch must have the same length, and the same text must embed to the same vector — ranking is keyed on that.

pub(open) trait Embedder {
  async fn embed(Self, ArrayView[String]) -> Array[Array[Double]]
}

traitLoader

Produces documents from somewhere — a file, a directory, an API, a literal string. Failure is part of the contract because the source may be unreadable or malformed; a loader that quietly returns nothing looks identical to an empty document and hides the problem.

pub(open) trait Loader {
  async fn load(Self) -> Array[Document]
}

traitRetriever

Answers a question in text: embeds it, searches, returns the best documents. A retriever is the whole read path behind one call; a reranker, a query rewrite, or MMR is an implementation of this trait and nothing above it changes.

pub(open) trait Retriever {
  async fn retrieve(Self, String, limit~ : Int32) -> Array[Scored]
}

traitSplitter

Cuts one document into smaller documents. Splitting is not async: it is pure text work with no I/O, and keeping it synchronous lets it run inside a parser or a test without an event loop.

pub(open) trait Splitter {
  fn split(Self, Document) -> Array[Document]
}

traitVectorStore

Where vectors live. add takes documents, not vectors: the store owns the embedder it was built with, so a caller never has to keep the two in step by hand. search takes the query's vector, because the query is often embedded once and searched in several stores, and because an embedding call is the expensive part a caller wants to place itself.

pub(open) trait VectorStore {
  async fn add(Self, Array[Document]) -> Array[String]
  async fn delete(Self, ArrayView[String]) -> Unit
  async fn search(Self, ArrayView[Double], limit~ : Int32, filter? : Filter) -> Array[Scored]
}

Functions

pub fn cosine_similarity(ArrayView[Double], ArrayView[Double]) -> Double raise

The cosine similarity of two vectors, in [-1, 1]: 1 for the same direction, 0 for orthogonal vectors or when either is all zeros, -1 for opposite directions. Raises Mismatch when the lengths differ. Cosine ignores magnitude, so a long document and a short one about the same thing score alike — which is why it is the usual ranking metric for text.

pub fn dot_product(ArrayView[Double], ArrayView[Double]) -> Double raise

The dot product of two vectors of the same length. Raises Mismatch when the lengths differ.

pub fn euclidean_distance(ArrayView[Double], ArrayView[Double]) -> Double raise

The Euclidean distance between two vectors: 0 for identical vectors, larger for further ones. Raises Mismatch when the lengths differ. Use it when the embedding model was trained on it; ranking by distance ascending and by similarity descending agree only for normalised vectors, so the two are kept apart rather than folded into one.

pub fn magnitude(ArrayView[Double]) -> Double

The Euclidean norm of a vector.

pub fn mmr(ArrayView[Double], ArrayView[Candidate], limit~ : Int32, lambda? : Double) -> Array[Scored] raise

Pick up to limit candidates that are relevant to query and unlike each other. Each round scores every remaining candidate as lambda * similarity to the query - (1 - lambda) * highest similarity to an already picked one, and takes the best; lambda = 1 degenerates to plain similarity, lambda = 0 to "show me the most novel document". Ties go to the earlier candidate, so the result is deterministic. Raises Mismatch when a candidate vector's length differs from the query's.

pub fn normalized(ArrayView[Double]) -> Array[Double]

vector scaled to unit length; an all-zero vector comes back unchanged rather than as NaNs.

pub fn rank(Array[Scored], Int32) -> Array[Scored]

hits sorted by score descending — equal scores keep their arrival order — cut to limit. The sort is stable on purpose: with a small corpus, several documents tie at cosine 1.0, and a caller re-running a search expects the same three each time.

split

Cutting a document into chunks: recursive separators, a token budget, Markdown sections and HTML sections.

structHtmlSplitter

Cuts an HTML document into one chunk per heading-delimited section. Each chunk's metadata carries the headings above it as h1 … h6, so a retrieved chunk can say which section it belongs to. A section longer than chunk_size is cut again by the recursive splitter with the same heading path, so no chunk outgrows an embedding window.

pub struct HtmlSplitter {
  chunk_size : Int32
  inner : RecursiveSplitter
}
pub fn HtmlSplitter::new(chunk_size? : Int32, chunk_overlap? : Int32, strip_whitespace? : Bool) -> Self raise

A splitter cutting sections of at most chunk_size code points; a section shorter than that stays whole. Raises Empty when chunk_size is not positive, and Exceeded when chunk_overlap is negative or larger than chunk_size.

pub fn HtmlSplitter::split(Self, @moonrag.Document) -> Array[@moonrag.Document]
pub fn HtmlSplitter::split_html(Self, String, meta? : Map[String, @json.Json]) -> Array[@moonrag.Document]

The chunks html splits into: one per section, or several when a section is over budget.

enumKeepSeparator

Where a separator goes relative to the piece it separated.

pub(all) enum KeepSeparator {
  Drop
  Start
  End
}

structMarkdownHeading

One heading level that starts a new section, and the metadata key its text is filed under. The key is the caller's: MarkdownHeading::new(2, "h2") files an ## Install heading as {"h2": "Install"}. Levels are unique within a splitter, so a section's path has one entry per level.

pub(all) struct MarkdownHeading {
  level : Int32
  key : String
}
pub fn MarkdownHeading::defaults() -> Array[Self]

The six ATX levels, filed as h1 … h6.

pub fn MarkdownHeading::new(Int32, String) -> Self raise

A heading level 1 to 6 filed under key. Raises Exceeded when level is outside that range and Empty when key is blank.

structMarkdownSplitter

Cuts a Markdown document at its headings. A chunk never crosses a heading, and carries the whole path down to it — h1, h2 and so on — so a retrieved passage can say which section of which page it came from. A section longer than chunk_size is cut again by the recursive splitter at block boundaries; a code block is emitted whole however long it is, because cutting it would leave a fragment that neither compiles nor reads.

pub struct MarkdownSplitter {
  chunk_size : Int32
  chunk_overlap : Int32
  headings : Array[MarkdownHeading]
  strip_headers : Bool
  fallback : RecursiveSplitter
}
pub fn MarkdownSplitter::new(chunk_size? : Int32, chunk_overlap? : Int32, headings? : Array[MarkdownHeading], strip_headers? : Bool) -> Self raise

A splitter producing sections of at most chunk_size code points. headings is the set of levels that start a new chunk; a heading of a level not listed stays in the text of the section around it. strip_headers drops the heading line itself from the chunk — on by default, because the heading is in the metadata and repeating it wastes an embedding slot. Raises Empty when chunk_size is not positive, Exceeded when chunk_overlap is negative or larger than chunk_size or when two headings share a level.

pub fn MarkdownSplitter::split(Self, @moonrag.Document) -> Array[@moonrag.Document]
pub fn MarkdownSplitter::split_markdown(Self, String, meta? : Map[String, @json.Json]) -> Array[@moonrag.Document]

The documents markdown splits into, filed under meta as well as their heading path — the same result as split on a document, for a caller that has the text and nothing else.

pub fn MarkdownSplitter::split_text(Self, String) -> Array[String]

The text of the chunks text splits into.

structRecursiveSplitter

Cuts text by trying a list of separators from coarse to fine. Paragraphs first, then lines, then words, then characters: a piece that still does not fit is split again by the next separator, so the result respects natural boundaries for as long as it can and only cuts mid-word when the text leaves no choice.

pub struct RecursiveSplitter {
  chunk_size : Int32
  chunk_overlap : Int32
  separators : Array[String]
  keep_separator : KeepSeparator
  strip_whitespace : Bool
  add_start_index : Bool
  measure : (StringView) -> Int32
}
pub fn RecursiveSplitter::new(chunk_size? : Int32, chunk_overlap? : Int32, separators? : Array[String], keep_separator? : KeepSeparator, strip_whitespace? : Bool, add_start_index? : Bool, measure? : (StringView) -> Int32) -> Self raise

A splitter producing pieces of at most chunk_size units, where a unit is one code point unless measure says otherwise. chunk_overlap carries that many units of the previous piece into the next one so a sentence cut across a boundary is still readable in one of them; the defaults (4000 and 200) are the ones most chunking pipelines assume. keep_separator decides whether the separator stays at the start of the following piece, at the end of the preceding one, or is dropped. Raises Empty when chunk_size is not positive, and Exceeded when chunk_overlap is negative or larger than chunk_size.

pub fn RecursiveSplitter::split(Self, @moonrag.Document) -> Array[@moonrag.Document]
pub fn RecursiveSplitter::split_text(Self, String) -> Array[String]

The chunks text splits into. Public because a caller sometimes wants the strings without the document bookkeeping.

pub fn RecursiveSplitter::split_with_offsets(Self, String) -> Array[(String, Int32)]

The chunks text splits into, paired with the offset each started at.

structTokenSplitter

Cuts text into chunks of at most chunk_size tokens, where measure counts tokens. The pieces the text is cut into are the units separator delimits (a space by default), and each chunk is measured with measure on the assembled text, so the promise holds for the caller's real tokenizer rather than for an estimate.

pub struct TokenSplitter {
  chunk_size : Int32
  chunk_overlap : Int32
  separator : String
  strip_whitespace : Bool
  measure : (StringView) -> Int32
}
pub fn TokenSplitter::new((StringView) -> Int32, chunk_size? : Int32, chunk_overlap? : Int32, separator? : String, strip_whitespace? : Bool) -> Self raise

A splitter whose chunk_size and chunk_overlap are counted in measure's units. Defaults are 512 and 64 tokens, the window most embedding models accept. Raises Empty when chunk_size is not positive, and Exceeded when chunk_overlap is negative or larger than chunk_size.

pub fn TokenSplitter::split(Self, @moonrag.Document) -> Array[@moonrag.Document]
pub fn TokenSplitter::split_text(Self, String) -> Array[String]

The chunks text splits into, each within the token budget.

Functions

pub fn html_text(String) -> String

The readable text of a HTML page: block boundaries become line breaks, markup, scripts, styles and headings-of-nothing are dropped. A loader and a splitter both read a page through this, so they cannot disagree about what it says.

pub fn html_title(String) -> String?

The page title: <title>, or the first h1 when the page has none.

load

Text, CSV, JSON, Markdown and HTML into documents, from bytes already in memory.

structCsvLoader

A CSV table, one document per row. The document text is the row spelled out as column: value lines, which reads better to a model than a comma-separated line, and every column is also in the metadata under its header name.

pub struct CsvLoader {
  source : String
  text : String
  has_header : Bool
  delimiter : Char
}
pub async fn CsvLoader::load(Self) -> Array[@moonrag.Document]
pub fn CsvLoader::new(String, String, has_header? : Bool, delimiter? : Char) -> Self

A loader over text. With has_header the first record names the columns; without it the columns are column_0, column_1, … Raises Malformed when a quoted field is never closed.

structHtmlLoader

A HTML page as one document of readable text.

pub struct HtmlLoader {
  source : String
  text : String
}
pub async fn HtmlLoader::load(Self) -> Array[@moonrag.Document]
pub fn HtmlLoader::new(String, String) -> Self

A loader over a HTML text.

structJsonLoader

A JSON document, one document per element when the top level is an array. With text_key the named field becomes the text and the rest of the object becomes metadata — which is how a corpus exported as [{"title": ..., "body": ...}] becomes documents without a transformation step. Without it, an object's text field is used, and failing that the object is written out as JSON so nothing is silently lost.

pub struct JsonLoader {
  source : String
  text : String
  text_key : String?
}
pub async fn JsonLoader::load(Self) -> Array[@moonrag.Document]
pub fn JsonLoader::new(String, String, text_key? : String) -> Self

A loader over a JSON text.

structMarkdownLoader

A Markdown file as one document, with its first heading as the title metadata.

pub struct MarkdownLoader {
  source : String
  text : String
}
pub async fn MarkdownLoader::load(Self) -> Array[@moonrag.Document]
pub fn MarkdownLoader::new(String, String) -> Self

A loader over a Markdown text.

structTextLoader

A whole text as a single document, with source recorded in its metadata. Use it for a note, a log line, a field already read from somewhere else: anything whose text is the document rather than a container for documents.

pub struct TextLoader {
  source : String
  text : String
}
pub async fn TextLoader::load(Self) -> Array[@moonrag.Document]
pub fn TextLoader::new(String, String) -> Self

A loader over text, labelling the document with source.

load/file

The same loaders reading from disk. Native only: a filesystem is not something every target has.

Functions

pub async fn csv(String, has_header? : Bool) -> Array[@moonrag.Document]

The CSV file at path, one document per row.

pub async fn html(String) -> Array[@moonrag.Document]

The HTML file at path, as readable text.

pub async fn json(String, text_key? : String) -> Array[@moonrag.Document]

The JSON file at path, one document per element when it holds an array.

pub async fn markdown(String) -> Array[@moonrag.Document]

The Markdown file at path, titled by its first heading.

pub async fn read(String) -> String

The whole file at path as text. Raises whatever the filesystem raises for a missing or unreadable file, and refuses text that is not valid UTF-8 rather than substituting replacement characters — a corpus with a silently mangled encoding is worse than one that fails to load.

pub async fn text(String) -> Array[@moonrag.Document]

The file at path as one document.

index

Incremental indexing: a content hash per id, so a second run over an unchanged corpus embeds nothing.

enumCleanup

What to do about documents that were indexed before and are absent from this run.

pub(all) enum Cleanup {
  Incremental
  Full
  None
}
Incremental

Delete the ones whose source appears in this run and whose id does not — the file was rewritten.

Full

Delete every one whose id does not appear, whoever its source.

None

Delete nothing: the run only adds and updates.

structIndexer

Keeps a store and a record of what it holds in step. index is the only operation: hand it the documents a source produces now, and it adds the new ones, replaces the changed ones, leaves the unchanged ones alone, and — depending on cleanup — removes the ones that disappeared.

pub struct Indexer {
  store : &@moonrag.VectorStore
  source_key : String
  mut records : Array[(String, Bytes, String?)]
}
pub fn Indexer::ids(Self) -> Array[String]

The ids the indexer holds, in the order they were first indexed.

pub async fn Indexer::index(Self, Array[@moonrag.Document], cleanup? : Cleanup) -> Stats

Bring the store in line with documents, returning what changed. A document whose id is already indexed with the same content is skipped, so the expensive part — embedding — does not happen twice. A document with the same id and different content replaces the stored one; there is never a second copy of one id.

pub fn Indexer::len(Self) -> Int32

The number of documents this indexer has recorded.

pub fn Indexer::new(&@moonrag.VectorStore, source_key? : String) -> Self

An indexer over store. source_key names the metadata key that identifies where a document came from; the default is source, the key every loader writes.

structStats

What one index call did.

pub(all) struct Stats {
  mut added : Int32
  mut updated : Int32
  mut skipped : Int32
  mut deleted : Int32
}

sql

The same store over a table, for any driver implementing moondb's AsyncDriver. PostgreSQL with pgvector ranks in the statement; SQLite ranks in this process.

structBlockingDriver

An AsyncDriver over a driver that blocks. SQLite reads a local file: there is nothing to wait for, so wrapping it in an async contract costs one trait implementation and no threads. A network backend should implement AsyncDriver itself, where the wait is real.

pub struct BlockingDriver[T] {
  inner : T
}
pub async fn[T : @moondb.Driver] BlockingDriver::begin(Self[T]) -> Unit raise @moondb.DbError
pub fn[T : @moondb.Driver] BlockingDriver::capabilities(Self[T]) -> @moondb.Capabilities
pub async fn[T : @moondb.Driver] BlockingDriver::close(Self[T]) -> Unit
pub async fn[T : @moondb.Driver] BlockingDriver::commit(Self[T]) -> Unit raise @moondb.DbError
pub fn[T : @moondb.Driver] BlockingDriver::dialect(Self[T]) -> @moondb.Dialect
pub async fn[T : @moondb.Driver] BlockingDriver::execute(Self[T], String, Array[@moondb.Value]) -> @moondb.ExecResult raise @moondb.DbError
pub fn[T] BlockingDriver::inner(Self[T]) -> T

The driver this adapter wraps.

pub fn[T] BlockingDriver::new(T) -> Self[T]

driver, presented as an asynchronous driver.

pub async fn[T : @moondb.Driver] BlockingDriver::ping(Self[T]) -> Bool
pub async fn[T : @moondb.Driver] BlockingDriver::prepare(Self[T], String) -> &@moondb.AsyncStmt raise @moondb.DbError
pub async fn[T : @moondb.Driver] BlockingDriver::query(Self[T], String, Array[@moondb.Value]) -> Array[@moondb.Row] raise @moondb.DbError
pub async fn[T : @moondb.Driver] BlockingDriver::query_stream(Self[T], String, Array[@moondb.Value]) -> &@moondb.AsyncCursor raise @moondb.DbError
pub async fn[T : @moondb.Driver] BlockingDriver::rollback(Self[T]) -> Unit raise @moondb.DbError

structSqlVectorStore

A VectorStore held in a SQL table, over any driver implementing moondb's AsyncDriver. dimension is the width of the vectors this store holds, fixed when it is constructed because the column has to be declared with it. table is the name to keep rows in; it must be a plain identifier, since it is written into the statement rather than bound as a value. Raises Empty when dimension is not positive, Malformed when table is not an identifier, and Unsupported for MySQL, which no test here reaches.

pub struct SqlVectorStore[T] {
  driver : T
  embedder : &@moonrag.Embedder
  dimension : Int32
  table : String
  mut counter : Int32
}
pub async fn[T : @moondb.AsyncDriver] SqlVectorStore::add(Self[T], Array[@moonrag.Document]) -> Array[String]
pub async fn[T : @moondb.AsyncDriver] SqlVectorStore::clear(Self[T]) -> Unit

Remove every stored document, keeping the table.

pub async fn[T : @moondb.AsyncDriver] SqlVectorStore::create(Self[T]) -> Unit

Create the table this store needs, and on PostgreSQL the extension and the index. Safe to call on every start: every statement is IF NOT EXISTS.

pub async fn[T : @moondb.AsyncDriver] SqlVectorStore::delete(Self[T], ArrayView[String]) -> Unit
pub async fn[T : @moondb.AsyncDriver] SqlVectorStore::get(Self[T], String) -> @moonrag.Document?

The document stored under id, or None.

pub async fn[T : @moondb.AsyncDriver] SqlVectorStore::len(Self[T]) -> Int64

The number of stored documents.

pub fn[T : @moondb.AsyncDriver] SqlVectorStore::new(T, &@moonrag.Embedder, dimension~ : Int32, table? : String) -> Self[T] raise