diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/neo4j.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/neo4j.adoc index 4396dbfd9..c8048d7a4 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/neo4j.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/vectordbs/neo4j.adoc @@ -13,7 +13,7 @@ Those indexes are powered by Lucene using a Hierarchical Navigable Small World G == Prerequisites -* A running Neo4j (5.13+) instance. The following options are available: +* A running Neo4j (5.15+) instance. The following options are available: ** link:https://hub.docker.com/_/neo4j[Docker] image ** link:https://neo4j.com/download/[Neo4j Desktop] ** link:https://neo4j.com/cloud/aura-free/[Neo4j Aura] diff --git a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfigurationIT.java b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfigurationIT.java index d42b3e005..b81f35e80 100644 --- a/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfigurationIT.java +++ b/spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/vectorstore/neo4j/Neo4jVectorStoreAutoConfigurationIT.java @@ -45,10 +45,10 @@ import static org.assertj.core.api.Assertions.assertThat; @Testcontainers public class Neo4jVectorStoreAutoConfigurationIT { - // Needs to be Neo4j 5.13+, because Neo4j 5.13 deprecated the used embedding storing + // Needs to be Neo4j 5.15+, because Neo4j 5.15 deprecated the used embedding storing // function. @Container - static Neo4jContainer neo4jContainer = new Neo4jContainer<>(DockerImageName.parse("neo4j:5.14")) + static Neo4jContainer neo4jContainer = new Neo4jContainer<>(DockerImageName.parse("neo4j:5.15")) .withRandomPassword(); List documents = List.of( diff --git a/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/Neo4jVectorStore.java b/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/Neo4jVectorStore.java index bd503306b..6515c551b 100644 --- a/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/Neo4jVectorStore.java +++ b/vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/Neo4jVectorStore.java @@ -311,26 +311,21 @@ public class Neo4jVectorStore implements VectorStore, InitializingBean { try (var session = this.driver.session(this.config.sessionConfig)) { session - .run("CREATE CONSTRAINT %s_unique_idx IF NOT EXISTS FOR (n:%s) REQUIRE n.id IS UNIQUE".formatted( + .run("CREATE CONSTRAINT %s IF NOT EXISTS FOR (n:%s) REQUIRE n.id IS UNIQUE".formatted( SchemaNames.sanitize(this.config.label + "_unique_idx").orElseThrow(), this.config.quotedLabel)) .consume(); - var vectorIndexExists = session - .run("SHOW INDEXES YIELD name WHERE name = $name RETURN count(*) > 0", - Map.of("name", this.config.indexName)) - .single() - .get(0) - .asBoolean(); - - if (!vectorIndexExists) { - var statement = "CALL db.index.vector.createNodeIndex($indexName, $label, $embeddingProperty, $embeddingDimension, $distanceType)"; - session.run(statement, - Map.of("indexName", this.config.indexName, "label", this.config.label, "embeddingProperty", - this.config.embeddingProperty, "embeddingDimension", this.config.embeddingDimension, - "distanceType", this.config.distanceType.name)) - .consume(); - session.run("CALL db.awaitIndexes()").consume(); - } + var statement = """ + CREATE VECTOR INDEX %s IF NOT EXISTS FOR (n:%s) ON (n.%s) + OPTIONS {indexConfig: { + `vector.dimensions`: %d, + `vector.similarity_function`: '%s' + }} + """.formatted(SchemaNames.sanitize(this.config.indexName, true).orElseThrow(), + this.config.quotedLabel, this.config.embeddingProperty, this.config.embeddingDimension, + this.config.distanceType.name); + session.run(statement).consume(); + session.run("CALL db.awaitIndexes()").consume(); } } diff --git a/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/Neo4jVectorStoreIT.java b/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/Neo4jVectorStoreIT.java index cd61c0d37..940db8579 100644 --- a/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/Neo4jVectorStoreIT.java +++ b/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/Neo4jVectorStoreIT.java @@ -39,10 +39,11 @@ import static org.assertj.core.api.Assertions.assertThat; @EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+") class Neo4jVectorStoreIT { - // Needs to be Neo4j 5.13+, because Neo4j 5.13 deprecated the used embedding storing + // Needs to be Neo4j 5.15+, because Neo4j 5.15 deprecated the old vector index + // creation // function. @Container - static Neo4jContainer neo4jContainer = new Neo4jContainer<>(DockerImageName.parse("neo4j:5.14")) + static Neo4jContainer neo4jContainer = new Neo4jContainer<>(DockerImageName.parse("neo4j:5.15")) .withRandomPassword(); List documents = List.of(