Skip to content
Get Started

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.

  • 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 INDEX statement, or the Neo4jClient::create_vector_index helper shown below.

Add the crate to your project:

Terminal window
cargo add rig-neo4j

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(())
}
  • 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. IndexConfig also lets you configure properties such as dimensions and the similarity function.
  • get_index(model, index_name) returns a VectorStoreIndex bound 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.