Neo4j
The rig-neo4j crate implements Rig’s VectorStoreIndex trait on top of Neo4j’s native vector index. Use it when your embeddings live alongside graph data and you want similarity search without moving vectors into a separate store.
Prerequisites
Section titled “Prerequisites”- Neo4j GenAI plugin for vector indexing. It is enabled by default on Neo4j Aura and can be installed on self-managed instances.
- A vector index must exist before you query it. Create one with the Neo4j browser, a Cypher
CREATE VECTOR INDEXstatement, or theNeo4jClient::create_vector_indexhelper shown below.
Add the crate to your project:
cargo add rig-neo4jMinimal example
Section titled “Minimal example”Connect, create a vector index over a node label, then run a similarity search. top_n takes a VectorSearchRequest and deserializes each hit into your type.
use rig::client::{EmbeddingsClient, ProviderClient};use rig::providers::openai;use rig::vector_store::{VectorSearchRequest, VectorStoreIndex};use rig_neo4j::{Neo4jClient, vector_index::IndexConfig};use serde::Deserialize;
// The struct used to deserialize search results. Field names must match the// node properties stored in Neo4j.#[derive(Deserialize, Debug)]struct Movie { title: String,}
#[tokio::main]async fn main() -> Result<(), anyhow::Error> { let openai_client = openai::Client::from_env()?; let model = openai_client.embedding_model(openai::TEXT_EMBEDDING_3_SMALL);
let neo4j_client = Neo4jClient::connect("neo4j://localhost:7687", "username", "password").await?;
// Create a vector index named "moviePlots" over `Movie` nodes. neo4j_client .create_vector_index(IndexConfig::new("moviePlots"), "Movie", &model) .await?;
// Reuse the SAME embedding model that produced the stored embeddings. let index = neo4j_client.get_index(model, "moviePlots").await?;
let req = VectorSearchRequest::builder() .query("a historical movie set in Quebec") .samples(5) .build();
let results = index.top_n::<Movie>(req).await?; println!("{results:#?}");
Ok(())}How it works
Section titled “How it works”Neo4jClient::connect(uri, user, password)opens a connection to the database.create_vector_index(IndexConfig::new(name), node_label, &model)creates a vector index over the embedding property of the given node label.IndexConfigalso lets you configure properties such as dimensions and the similarity function.get_index(model, index_name)returns aVectorStoreIndexbound to an existing index. Pass the same embedding model that generated the stored vectors so queries are embedded consistently.index.top_n::<T>(request)returns the closest matches as(score, id, T)tuples;index.top_n_ids(request)returns just(score, id)when you only need identifiers.
Vectors are stored on your nodes, so you can combine similarity search with ordinary Cypher graph traversals. See the rig-neo4j examples for an end-to-end flow that embeds documents, writes them to Neo4j, and queries the index.
See also
Section titled “See also”- Vector Stores overview — shared
VectorStoreIndex/VectorSearchRequestconcepts. - Vector Stores & RAG — how retrieval fits into an agent.
- Neo4j vector index documentation.
