Search

Three search modes built on PostgreSQL: BM25 full-text search via pg_textsearch, vector similarity via pgvector, and hybrid combining both.

Full-Text Search

Uses BM25 ranking for relevance-scored text search. Requires enableFullTextSearch: true in setup (the default).

const results = await fs.textSearch("machine learning", {
  path: "/docs",    // scope to subdirectory (default: "/")
  limit: 20,        // max results (default: 20, max: 100)
})
// [{ path: "/docs/ml-intro.md", name: "ml-intro.md", rank: 1.42 }, ...]

Semantic Search

Vector-based similarity search using embeddings. Requires pgvector, enableVectorSearch: true in setup, and an embed function on the filesystem instance.

const results = await fs.semanticSearch("how do LLMs work", {
  path: "/docs",
  limit: 10,
})
// [{ path: "/docs/llm-guide.md", name: "llm-guide.md", rank: 0.92 }, ...]

Hybrid Search

Combines BM25 and vector scores with configurable weights. Requires both full-text and vector search to be enabled.

const results = await fs.hybridSearch("transformer architecture", {
  path: "/docs",
  textWeight: 0.4,     // BM25 weight (default: 0.4)
  vectorWeight: 0.6,   // vector weight (default: 0.6)
  limit: 20,
})

SearchResult

PropertyTypeDescription
pathstringFull path to the matching file
namestringFilename
ranknumberRelevance score (higher = more relevant)
snippetstring?Optional text snippet with match context

Embedding Function

For semantic and hybrid search, provide an embed function when creating the filesystem. Embeddings are computed automatically on writeFile and appendFile.

import { PgFileSystem } from "bash-gres/postgres"

const fs = new PgFileSystem({
  db: sql,
  workspaceId: "workspace-1",
  embed: async (text) => {
    const res = await openai.embeddings.create({
      model: "text-embedding-3-small",
      input: text,
    })
    return res.data[0].embedding
  },
  embeddingDimensions: 1536,
})

Search Options

OptionTypeDefaultDescription
pathstring"/"Scope search to a subdirectory
limitnumber20Max results (clamped to 1–100)
textWeightnumber0.4BM25 weight in hybrid search
vectorWeightnumber0.6Vector weight in hybrid search