Skip to content

Vector Search

lostcause edited this page Aug 24, 2026 · 1 revision

Vector search & embeddings

Nodes may carry a vector field; the property graph's vectors property indexes them for similarity search, and GraphQuery/PersistedGraphQuery can rank or filter by similarity.

Distance & indexes

  • new VectorIndex(onChange?, distanceFn?) — an exact in-memory index. add, addMany, remove, removeMany, clear, has, get, entries, size manage vectors. add/addMany invoke onChange for each id; hydrate(id, vector) sets a vector without triggering onChange, for restoring persisted state without marking it dirty again. query(vector, topK, threshold?) returns { id, score }[], highest first.
  • cosineSimilarity(a, b) and euclideanSimilarity(a, b) are built in. All compared vectors must have identical dimensions, or similarity functions throw RangeError. Zero vectors have cosine similarity 0. Added vectors are copied; get()/entries() return detached arrays.
  • HNSWIndex (new HNSWIndex(onChange?, distanceFn?, config?, rng?)) is an approximate, update-safe alternative implementing the same VectorIndexLike surface. config accepts M, Mmax0, efConstruction, efSearch (all optional, cosine distance by default — each must be a positive integer or the constructor throws RangeError).

Swap the engine backing a graph's vectors property via the constructor's createVectorIndex hook — it accepts anything implementing VectorIndexLike (VectorIndex, HNSWIndex, or the native engines from @0xx0lostcause0xx0/polypack-native):

import { PolyGraph, HNSWIndex } from '@0xx0lostcause0xx0/polypack'

const graph = new PolyGraph(undefined, undefined, undefined, undefined, (onChange) => new HNSWIndex(onChange))

Text embeddings

  • EmbeddingProvider defines embed(text) (sync or async, returning a number array, Float32Array, or Float64Array) and an optional dimensions.

  • FeatureHashEmbedding is the default, dependency-free provider — deterministic, normalized 384-dimensional lexical vectors, no model download. It captures shared words rather than learned semantic meaning; use a model-backed provider when synonyms and deeper language relationships matter. Its dimensions are configurable in the constructor.

  • Pass a custom provider as the third PolyGraph constructor argument:

    const provider = {
      dimensions: 768,
      async embed(text: string) {
        return model.embed(text)
      },
    }
    const graph = new PolyGraph(adapter, 10_000, provider)
  • embed(text) — generates and validates a detached Float64Array.

  • addNodeWithEmbedding(node, text) — adds a node using generated text features.

  • updateNodeWithEmbedding(id, data, text) / updateNodeSafeWithEmbedding(id, data, text) — regenerate a node vector.

  • queryText / queryPersistedText — see Query builder.

Keep one provider and dimensionality per vector index — similarity comparisons reject vectors with mismatched dimensions.

Weighted embedding text

buildEmbeddingText(data, weights?) repeats fields according to weight (default 1) so the feature-hash bag-of-words embedding treats higher-weighted fields as more significant:

import { buildEmbeddingText } from '@0xx0lostcause0xx0/polypack'

buildEmbeddingText({ subject: 'Hello', content: 'World' }, { subject: 3 })
// => "Hello Hello Hello World"

Back to Home.

Clone this wiki locally