Add support for returning SearchResult from repository query methods.

Closes: #4960
This commit is contained in:
Mark Paluch
2025-04-10 11:49:05 +02:00
parent d850b9ef06
commit eab7aae16c
56 changed files with 2047 additions and 104 deletions

View File

@@ -45,6 +45,7 @@
** xref:repositories/create-instances.adoc[]
** xref:repositories/query-methods-details.adoc[]
** xref:mongodb/repositories/query-methods.adoc[]
** xref:mongodb/repositories/vector-search.adoc[]
** xref:mongodb/repositories/modifying-methods.adoc[]
** xref:repositories/projections.adoc[]
** xref:repositories/custom-implementations.adoc[]

View File

@@ -0,0 +1,8 @@
:vector-search-intro-include: data-mongodb::partial$vector-search-intro-include.adoc
:vector-search-model-include: data-mongodb::partial$vector-search-model-include.adoc
:vector-search-repository-include: data-mongodb::partial$vector-search-repository-include.adoc
:vector-search-scoring-include: data-mongodb::partial$vector-search-scoring-include.adoc
:vector-search-method-derived-include: data-mongodb::partial$vector-search-method-derived-include.adoc
:vector-search-method-annotated-include: data-mongodb::partial$vector-search-method-annotated-include.adoc
include::{commons}@data-commons::page$repositories/vector-search.adoc[]

View File

@@ -0,0 +1 @@
To use Vector Search with MongoDB, you need a MongoDB Atlas instance that is either running in the cloud or by using https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-deploy-docker/[Docker].

View File

@@ -0,0 +1,23 @@
Annotated search methods use the `@VectorSearch` annotation to define parameters for the https://www.mongodb.com/docs/upcoming/reference/operator/aggregation/vectorSearch/[`$vectorSearch`] aggregation stage.
.Using `@VectorSearch` Search Methods
====
[source,java]
----
interface CommentRepository extends Repository<Comment, String> {
@VectorSearch(indexName = "cos-index", filter = "{country: ?0}")
SearchResults<WithVector> searchAnnotatedByCountryAndEmbeddingWithin(String country, Vector embedding,
Score distance);
@VectorSearch(indexName = "my-index", filter = "{country: ?0}", numCandidates = "#{#limit * 20}",
searchType = VectorSearchOperation.SearchType.ANN)
List<WithVector> findAnnotatedByCountryAndEmbeddingWithin(String country, Vector embedding, Score distance, int limit);
}
----
====
Annotated Search Methods can define `filter` for pre-filter usage.
`filter`, `limit`, and `numCandidates` support xref:page$mongodb/value-expressions.adoc[Value Expressions] allowing references to search method arguments.

View File

@@ -0,0 +1,21 @@
MongoDB Search methods must use the `@VectorSearch` annotation to define the index name for the https://www.mongodb.com/docs/upcoming/reference/operator/aggregation/vectorSearch/[`$vectorSearch`] aggregation stage.
.Using `Near` and `Within` Keywords in Repository Search Methods
====
[source,java]
----
interface CommentRepository extends Repository<Comment, String> {
@VectorSearch(indexName = "my-index")
SearchResults<Comment> searchByEmbeddingNear(Vector vector, Score score);
@VectorSearch(indexName = "my-index")
SearchResults<Comment> searchByEmbeddingWithin(Vector vector, Range<Similarity> range);
@VectorSearch(indexName = "my-index")
SearchResults<Comment> searchByCountryAndEmbeddingWithin(String country, Vector vector, Range<Similarity> range);
}
----
====
Derived Search Methods can define domain model attributes to create the pre-filter for indexed fields.

View File

@@ -0,0 +1,15 @@
====
[source,java]
----
class Comment {
@Id String id;
String country;
String comment;
Vector embedding;
// getters, setters, …
}
----
====

View File

@@ -0,0 +1,19 @@
.Using `SearchResult<T>` in a Repository Search Method
====
[source,java]
----
interface CommentRepository extends Repository<Comment, String> {
@VectorSearch(indexName = "my-index")
SearchResults<Comment> searchByCountryAndEmbeddingNear(String country, Vector vector, Score score,
Limit limit);
@VectorSearch(indexName = "my-index")
SearchResults<WithVector> searchAnnotatedByCountryAndEmbeddingWithin(String country, Vector embedding,
Score score);
}
SearchResults<Comment> results = repository.searchByCountryAndEmbeddingNear("en", Vector.of(…), Score.of(0.9), Limit.of(10));
----
====

View File

@@ -0,0 +1,32 @@
MongoDB reports the score directly as similarity value.
The scoring function must be specified in the index and therefore, Vector search methods do not consider the `Score.scoringFunction`.
The scoring function defaults to `ScoringFunction.unspecified()` as there is no information inside of search results how the score has been computed.
.Using `Score` and `Similarity` in a Repository Search Methods
====
[source,java]
----
interface CommentRepository extends Repository<Comment, String> {
@VectorSearch(…)
SearchResults<Comment> searchByEmbeddingNear(Vector vector, Score similarity);
@VectorSearch(…)
SearchResults<Comment> searchByEmbeddingNear(Vector vector, Similarity similarity);
@VectorSearch(…)
SearchResults<Comment> searchByEmbeddingNear(Vector vector, Range<Similarity> range);
}
repository.searchByEmbeddingNear(Vector.of(…), Score.of(0.9)); <1>
repository.searchByEmbeddingNear(Vector.of(…), Similarity.of(0.9)); <2>
repository.searchByEmbeddingNear(Vector.of(…), Similarity.between(0.5, 1)); <3>
----
<1> Run a search and return results with a similarity of `0.9` or greater.
<2> Return results with a similarity of `0.9` or greater.
<3> Return results with a similarity of between `0.5` and `1.0` or greater.
====