Skip to content

Commit 8586fb2

Browse files
committed
Docs
Signed-off-by: Gerrit Meier <[email protected]>
1 parent 86e6a26 commit 8586fb2

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

src/main/antora/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
** xref:repositories/sdn-extension.adoc[]
2727
** xref:repositories/query-keywords-reference.adoc[]
2828
** xref:repositories/query-return-types-reference.adoc[]
29+
** xref:repositories/vector-search.adoc[]
2930
3031
* xref:repositories/projections.adoc[]
3132
** xref:projections/sdn-projections.adoc[]
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[[sdn-vector-search]]
2+
= Neo4j Vector Search
3+
4+
== The `@VectorSearch` annotation
5+
Spring Data Neo4j supports Neo4j's vector search on the repository level by using the `@VectorSearch` annotation.
6+
For this to work, Neo4j needs to have a vector index in place.
7+
How to create a vector index is explained in the https://neo4j.com/docs/cypher-manual/current/indexes/search-performance-indexes/managing-indexes/[Neo4j documentation].
8+
9+
NOTE: It's not required to have any (Spring Data) Vector typed property be defined in the domain entities for this to work
10+
because the search operates exclusively on the index.
11+
12+
The `@VectorSearch` annotation requires two arguments:
13+
The name of the vector index to be used and the number of nearest neighbours.
14+
15+
For a general vector search over the whole domain, it's possible to use a derived finder method without any property.
16+
[source,java,indent=0,tabsize=4]
17+
----
18+
include::example$integration/imperative/VectorSearchIT.java[tags=sdn-vector-search.usage;sdn-vector-search.usage.findall]
19+
----
20+
21+
The vector index can be combined with any property-based finder method to filter down the results.
22+
23+
NOTE: For technical reasons, the vector search will always be executed before the property search gets invoked.
24+
E.g. if the property filter looks for a person named "Helge",
25+
but the vector search only yields "Hannes", there won't be a result.
26+
27+
[source,java,indent=0,tabsize=4]
28+
----
29+
include::example$integration/imperative/VectorSearchIT.java[tags=sdn-vector-search.usage;sdn-vector-search.usage.findbyproperty]
30+
----

src/main/java/org/springframework/data/neo4j/repository/query/VectorSearch.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
@Retention(RetentionPolicy.RUNTIME)
3030
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
3131
@Documented
32-
// @Query
3332
public @interface VectorSearch {
3433

3534
String indexName();

src/test/java/org/springframework/data/neo4j/integration/imperative/VectorSearchIT.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void setupData(@Autowired BookmarkCapture bookmarkCapture, @Autowired Driver dri
6060
try (Session session = driver.session(bookmarkCapture.createSessionConfig())) {
6161
session.run("MATCH (n) detach delete n");
6262
session.run("""
63-
CREATE VECTOR INDEX dingsIndex IF NOT EXISTS
63+
CREATE VECTOR INDEX entityIndex IF NOT EXISTS
6464
FOR (m:EntityWithVector)
6565
ON m.myVector
6666
OPTIONS { indexConfig: {
@@ -81,7 +81,7 @@ void setupData(@Autowired BookmarkCapture bookmarkCapture, @Autowired Driver dri
8181
@AfterEach
8282
void removeIndex(@Autowired BookmarkCapture bookmarkCapture, @Autowired Driver driver) {
8383
try (Session session = driver.session(bookmarkCapture.createSessionConfig())) {
84-
session.run("DROP INDEX `dingsIndex` IF EXISTS");
84+
session.run("DROP INDEX `entityIndex` IF EXISTS");
8585
}
8686
}
8787

@@ -128,24 +128,33 @@ void dontFindByNameWithVectorIndexAndScore(@Autowired VectorSearchRepository rep
128128
assertThat(result).hasSize(0);
129129
}
130130

131+
// tag::sdn-vector-search.usage[]
131132
interface VectorSearchRepository extends Neo4jRepository<EntityWithVector, String> {
132133

133-
@VectorSearch(indexName = "dingsIndex", numberOfNodes = 2)
134+
// end::sdn-vector-search.usage[]
135+
// tag::sdn-vector-search.usage.findall[]
136+
@VectorSearch(indexName = "entityIndex", numberOfNodes = 2)
134137
List<EntityWithVector> findBy(String name, Vector searchVector);
138+
// end::sdn-vector-search.usage.findall[]
135139

136-
@VectorSearch(indexName = "dingsIndex", numberOfNodes = 1)
140+
// tag::sdn-vector-search.usage.findbyproperty[]
141+
@VectorSearch(indexName = "entityIndex", numberOfNodes = 1)
137142
List<EntityWithVector> findByName(String name, Vector searchVector);
143+
// end::sdn-vector-search.usage.findbyproperty[]
138144

139-
@VectorSearch(indexName = "dingsIndex", numberOfNodes = 2)
145+
@VectorSearch(indexName = "entityIndex", numberOfNodes = 2)
140146
List<EntityWithVector> findByName(String name, Vector searchVector, Score score);
141147

142-
@VectorSearch(indexName = "dingsIndex", numberOfNodes = 2)
148+
@VectorSearch(indexName = "entityIndex", numberOfNodes = 2)
143149
SearchResults<EntityWithVector> findAllBy(Vector searchVector);
144150

145-
@VectorSearch(indexName = "dingsIndex", numberOfNodes = 2)
151+
@VectorSearch(indexName = "entityIndex", numberOfNodes = 2)
146152
SearchResult<EntityWithVector> findBy(Vector searchVector, Score score);
147153

154+
// tag::sdn-vector-search.usage[]
155+
148156
}
157+
// end::sdn-vector-search.usage[]
149158

150159
@Configuration
151160
@EnableTransactionManagement

0 commit comments

Comments
 (0)