Skip to main content
TuringDB has a built-in vector index that lets you run k-nearest-neighbor searches over embedding vectors. You bring your own embeddings, from any model or provider, and TuringDB handles the indexing, storage, and fast retrieval. Each vector is associated with a numerical ID. That ID can be a node property, an edge property, or a foreign key referencing data in an external system. This keeps the index lightweight and flexible: the vector store doesn’t need to know what your data looks like.
Vector indexes live at the TuringDB root level, independent of graphs and versioning. A single vector index can serve searches across multiple graphs and commits.

Create a vector index

A vector index is defined by a name, a dimension, and a distance metric. Syntax:

Load embeddings

Once the index exists, load your pre-computed embeddings from a file. Each row in the file maps a numerical ID to a vector. The file path is relative to your TuringDB data directory (~/.turing/data by default).
The TuringDB data directory defaults to ~/.turing/data. You can change it at startup with the -turing-dir flag.
Syntax:
VECTOR SEARCH finds the k nearest neighbors of a query vector and yields their IDs. It is a read statement, so you can chain it with MATCH to pull back the actual graph data. Syntax:

Combining with MATCH

This is where it gets interesting. Chain VECTOR SEARCH with a MATCH clause to join the nearest-neighbor IDs back to your graph:
The ids variable works exactly like a variable introduced by CALL ... YIELD, so any subsequent MATCH clause can reference it.

Manage indexes

List all vector indexes

Delete a vector index

This removes the index and frees the associated resources.

Complete workflow

Embeddings as node properties

The vector index above is a standalone, root-level structure keyed by numeric IDs. Separately, you can store an embedding directly as a node or edge property (type Embedding) and compare embeddings inline with the cosine_similarity and euclidean_distance functions — no index required. Embedding literals use parentheses (...), not square brackets (which are list literals):

Bulk-loading embeddings from Parquet — LOAD EMBEDDING FROM

To attach embeddings to existing nodes in bulk, load them from a Parquet file. This is a write, so run it inside a change. Syntax:
The Parquet file (relative to the TuringDB data directory) must have exactly two columns:
The named property is created with type Embedding. The load fails if any node_id is missing from the graph, or if the property name already exists with a non-embedding type.
When importing a graph from JSONL, you can mark embedding properties at load time instead — see LOAD JSONL ... WITH EMBEDDINGS.