AshNeo4j.Vector (AshNeo4j v0.10.1)

Copy Markdown View Source

Convenience helpers for creating the Neo4j VECTOR indexes that back AshNeo4j.Type.Vector attributes.

Requires Cypher 25 (Neo4j ≥ 2025.06). Operations against an older server return {:error, %AshNeo4j.Error.RequiresCypher25{}}.

# Create the index for a vector attribute
AshNeo4j.Vector.create_index(Item, :embedding)

# Rebuild after a dimension or similarity-function change
AshNeo4j.Vector.create_index(Item, :embedding, recreate: true)

# Euclidean distance instead of the default cosine
AshNeo4j.Vector.create_index(Item, :embedding, similarity_function: :euclidean)

Consistent with AshNeo4j's "no automatic migrations" stance — this is an ergonomic tool you call (e.g. from a start-up task). create_index/3 uses IF NOT EXISTS, so it is safe to run repeatedly.

Naming

The index is named <base>_vector where base defaults to <label_lower>_<property> — e.g. item_embedding_vector. Pass :name to override the base.

Dry run

index_statements/3 returns the CREATE Cypher without touching the database — useful for review or testing.

Summary

Functions

Creates the VECTOR index for attr on resource.

Drops the VECTOR index for attr. Uses IF EXISTS, so it is a no-op when absent.

Returns {:ok, statement} — the CREATE VECTOR INDEX Cypher that create_index/3 would run — without touching the database.

Functions

create_index(resource, attr, opts \\ [])

@spec create_index(Ash.Resource.t(), atom(), keyword()) ::
  {:ok, Bolty.Response.t()} | {:error, term()}

Creates the VECTOR index for attr on resource.

Returns {:ok, %Bolty.Response{}} or {:error, reason}.

Options

  • :recreateDROP INDEX ... IF EXISTS before CREATE. Use after changing :dimensions or :similarity_function. Defaults to false.
  • :name — override the auto-derived base name. _vector is still appended.
  • :similarity_function:cosine (default) or :euclidean.

drop_index(resource, attr, opts \\ [])

@spec drop_index(Ash.Resource.t(), atom(), keyword()) ::
  {:ok, Bolty.Response.t()} | {:error, term()}

Drops the VECTOR index for attr. Uses IF EXISTS, so it is a no-op when absent.

index_statements(resource, attr, opts \\ [])

@spec index_statements(Ash.Resource.t(), atom(), keyword()) ::
  {:ok, String.t()} | {:error, term()}

Returns {:ok, statement} — the CREATE VECTOR INDEX Cypher that create_index/3 would run — without touching the database.

AshNeo4j.Vector.index_statements(Item, :embedding)
#=> {:ok, "CREATE VECTOR INDEX item_embedding_vector IF NOT EXISTS FOR (n:Item) ON (n.embedding) OPTIONS {indexConfig: {`vector.dimensions`: 1536, `vector.similarity_function`: 'cosine'}}"}