Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ec86ddb

Browse files
Docs
Signed-off-by: Gerrit Meier <meistermeier@gmail.com>
1 parent b2e51d0 commit ec86ddb

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)

AltStyle によって変換されたページ (->オリジナル) /