Skip to content

Commit f0ffa4f

Browse files
committed
Polishing.
1 parent 7cc48a0 commit f0ffa4f

File tree

10 files changed

+303
-66
lines changed

10 files changed

+303
-66
lines changed

src/main/java/org/springframework/data/domain/Range.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ public boolean contains(T value, Comparator<T> comparator) {
223223
/**
224224
* Apply a mapping {@link Function} to the lower and upper boundary values.
225225
*
226-
* @param mapper must not be {@literal null}. If the mapper returns {@code null}, then the corresponding boundary
226+
* @param mapper must not be {@literal null}. If the mapper returns {@literal null}, then the corresponding boundary
227227
* value represents an {@link Bound#unbounded()} boundary.
228228
* @return a new {@link Range} after applying the value to the mapper.
229229
* @param <R> target type of the mapping function.
@@ -430,7 +430,7 @@ public boolean isInclusive() {
430430
/**
431431
* Apply a mapping {@link Function} to the boundary value.
432432
*
433-
* @param mapper must not be {@literal null}. If the mapper returns {@code null}, then the boundary value
433+
* @param mapper must not be {@literal null}. If the mapper returns {@literal null}, then the boundary value
434434
* corresponds with {@link Bound#unbounded()}.
435435
* @return a new {@link Bound} after applying the value to the mapper.
436436
* @param <R>

src/main/java/org/springframework/data/domain/Score.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,18 @@
2020
import org.springframework.util.ObjectUtils;
2121

2222
/**
23-
* Value object to represent search result scores determined by a {@link ScoringFunction}. Scores are used to rank
24-
* search results and typically, a higher score indicates a more relevant result.
23+
* Value object representing a search result score computed via a {@link ScoringFunction}.
24+
* <p>
25+
* Encapsulates the numeric score and the scoring function used to derive it. Scores are primarily used to rank search
26+
* results. Depending on the used {@link ScoringFunction} higher scores can indicate either a higher distance or a
27+
* higher similarity. Use the {@link Similarity} class to indicate usage of a normalized score across representing
28+
* effectively the similarity.
29+
* <p>
30+
* Instances of this class are immutable and suitable for use in comparison, sorting, and range operations.
2531
*
2632
* @author Mark Paluch
2733
* @since 4.0
34+
* @see Similarity
2835
*/
2936
public sealed class Score implements Serializable permits Similarity {
3037

@@ -37,13 +44,13 @@ public sealed class Score implements Serializable permits Similarity {
3744
}
3845

3946
/**
40-
* Creates a new {@link Score} from a plain {@code score} value using {@link ScoringFunction#UNSPECIFIED}.
47+
* Creates a new {@link Score} from a plain {@code score} value using {@link ScoringFunction#unspecified()}.
4148
*
4249
* @param score the score value without a specific {@link ScoringFunction}.
4350
* @return the new {@link Score}.
4451
*/
4552
public static Score of(double score) {
46-
return of(score, ScoringFunction.UNSPECIFIED);
53+
return of(score, ScoringFunction.unspecified());
4754
}
4855

4956
/**
@@ -58,20 +65,30 @@ public static Score of(double score, ScoringFunction function) {
5865
}
5966

6067
/**
61-
* Creates a {@link Range} between the given {@link Score}.
68+
* Creates a {@link Range} from the given minimum and maximum {@code Score} values.
6269
*
63-
* @param min can be {@literal null}.
64-
* @param max can be {@literal null}.
65-
* @return will never be {@literal null}.
70+
* @param min the lower score value, must not be {@literal null}.
71+
* @param max the upper score value, must not be {@literal null}.
72+
* @return a {@link Range} over {@link Score} bounds.
6673
*/
6774
public static Range<Score> between(Score min, Score max) {
6875
return Range.from(Range.Bound.inclusive(min)).to(Range.Bound.inclusive(max));
6976
}
7077

78+
/**
79+
* Returns the raw numeric value of the score.
80+
*
81+
* @return the score value.
82+
*/
7183
public double getValue() {
7284
return value;
7385
}
7486

87+
/**
88+
* Returns the {@link ScoringFunction} that was used to compute this score.
89+
*
90+
* @return the associated scoring function.
91+
*/
7592
public ScoringFunction getFunction() {
7693
return function;
7794
}

src/main/java/org/springframework/data/domain/ScoringFunction.java

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,72 @@
1616
package org.springframework.data.domain;
1717

1818
/**
19+
* Strategy interface for scoring functions.
20+
* <p>
21+
* Implementations define how score (distance or similarity) between two vectors is computed, allowing control over
22+
* ranking behavior in search queries.
23+
* <p>
24+
* Provides commonly used scoring variants via static factory methods. See {@link VectorScoringFunctions} for the
25+
* concrete implementations.
26+
*
1927
* @author Mark Paluch
2028
* @since 4.0
29+
* @see Score
30+
* @see Similarity
2131
*/
2232
public interface ScoringFunction {
2333

2434
/**
25-
* The default {@link ScoringFunction} when none is specified.
35+
* Returns the default {@code ScoringFunction} to be used when none is explicitly specified.
36+
* <p>
37+
* This is typically used to indicate the absence of a scoring definition.
38+
*
39+
* @return the default {@code ScoringFunction} instance.
40+
*/
41+
static ScoringFunction unspecified() {
42+
return UnspecifiedScoringFunction.INSTANCE;
43+
}
44+
45+
/**
46+
* Return the Euclidean distance scoring function.
47+
* <p>
48+
* Calculates the L2 norm (straight-line distance) between two vectors.
49+
*
50+
* @return the {@code ScoringFunction} based on Euclidean distance.
51+
*/
52+
static ScoringFunction euclidean() {
53+
return VectorScoringFunctions.EUCLIDEAN;
54+
}
55+
56+
/**
57+
* Return the cosine similarity scoring function.
58+
* <p>
59+
* Measures the cosine of the angle between two vectors, independent of magnitude.
60+
*
61+
* @return the {@code ScoringFunction} based on cosine similarity.
2662
*/
27-
ScoringFunction UNSPECIFIED = UnspecifiedScoringFunction.INSTANCE;
63+
static ScoringFunction cosine() {
64+
return VectorScoringFunctions.COSINE;
65+
}
2866

67+
/**
68+
* Return the dot product (inner product) scoring function.
69+
* <p>
70+
* Computes the algebraic product of two vectors, considering both direction and magnitude.
71+
*
72+
* @return the {@code ScoringFunction} based on dot product.
73+
*/
74+
static ScoringFunction dotProduct() {
75+
return VectorScoringFunctions.DOT_PRODUCT;
76+
}
77+
78+
/**
79+
* Return the name of the scoring function.
80+
* <p>
81+
* Typically used for display or configuration purposes.
82+
*
83+
* @return the identifying name of this scoring function.
84+
*/
2985
String getName();
86+
3087
}

src/main/java/org/springframework/data/domain/SearchResult.java

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,17 @@
2525
import org.springframework.util.ObjectUtils;
2626

2727
/**
28-
* Value object capturing some arbitrary object plus a distance.
28+
* Immutable value object representing a search result consisting of a content item and an associated {@link Score}.
29+
* <p>
30+
* Typically used in the context of similarity-based or vector search operations where each result carries a relevance
31+
* {@link Score}. Provides accessor methods for the content and its score, along with transformation support via
32+
* {@link #map(Function)}.
2933
*
34+
* @param <T> the type of the content object
3035
* @author Mark Paluch
3136
* @since 4.0
37+
* @see Score
38+
* @see Similarity
3239
*/
3340
public final class SearchResult<T> implements Serializable {
3441

@@ -37,6 +44,12 @@ public final class SearchResult<T> implements Serializable {
3744
private final T content;
3845
private final Score score;
3946

47+
/**
48+
* Creates a new {@link SearchResult} with the given content and {@link Score}.
49+
*
50+
* @param content the result content, must not be {@literal null}.
51+
* @param score the result score, must not be {@literal null}.
52+
*/
4053
public SearchResult(T content, Score score) {
4154

4255
Assert.notNull(content, "Content must not be null");
@@ -46,18 +59,44 @@ public SearchResult(T content, Score score) {
4659
this.score = score;
4760
}
4861

62+
/**
63+
* Create a new {@link SearchResult} with the given content and a raw score value.
64+
*
65+
* @param content the result content, must not be {@literal null}.
66+
* @param score the score value.
67+
*/
4968
public SearchResult(T content, double score) {
5069
this(content, Score.of(score));
5170
}
5271

72+
/**
73+
* Returns the content associated with this result.
74+
*/
5375
public T getContent() {
5476
return this.content;
5577
}
5678

79+
/**
80+
* Returns the {@link Score} associated with this result.
81+
*/
5782
public Score getScore() {
5883
return this.score;
5984
}
6085

86+
/**
87+
* Creates a new {@link SearchResult} by applying the given mapping {@link Function} to this result's content.
88+
*
89+
* @param converter the mapping function to apply to the content, must not be {@literal null}.
90+
* @return a new {@link SearchResult} instance with converted content.
91+
* @param <U> the target type of the mapped content.
92+
*/
93+
public <U> SearchResult<U> map(Function<? super T, ? extends U> converter) {
94+
95+
Assert.notNull(converter, "Function must not be null");
96+
97+
return new SearchResult<>(converter.apply(getContent()), getScore());
98+
}
99+
61100
@Override
62101
public boolean equals(@Nullable Object o) {
63102

@@ -86,17 +125,4 @@ public String toString() {
86125
return String.format("SearchResult [content: %s, score: %s]", content, score);
87126
}
88127

89-
/**
90-
* Returns new {@link SearchResults} with the content of the current one mapped by the given {@link Function}.
91-
*
92-
* @param converter must not be {@literal null}.
93-
* @return a new {@link SearchResults} with the content of the current one mapped by the given {@link Function}.
94-
*/
95-
public <U> SearchResult<U> map(Function<? super T, ? extends U> converter) {
96-
97-
Assert.notNull(converter, "Function must not be null");
98-
99-
return new SearchResult<>(converter.apply(getContent()), getScore());
100-
}
101-
102128
}

src/main/java/org/springframework/data/domain/SearchResults.java

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,39 @@
2121
import java.util.List;
2222
import java.util.function.Function;
2323
import java.util.stream.Collectors;
24+
import java.util.stream.Stream;
2425

26+
import org.springframework.data.util.Streamable;
2527
import org.springframework.util.Assert;
2628
import org.springframework.util.ObjectUtils;
2729
import org.springframework.util.StringUtils;
2830

2931
/**
30-
* Value object to capture {@link SearchResult}s.
32+
* Value object encapsulating a collection of {@link SearchResult} instances.
33+
* <p>
34+
* Typically used as the result type for search or similarity queries, exposing access to the result content and
35+
* supporting mapping operations to transform the result content type.
3136
*
37+
* @param <T> the type of content contained within each {@link SearchResult}.
3238
* @author Mark Paluch
3339
* @since 4.0
40+
* @see SearchResult
3441
*/
3542
public class SearchResults<T> implements Iterable<SearchResult<T>>, Serializable {
3643

3744
private final List<? extends SearchResult<T>> results;
3845

39-
public SearchResults(List<SearchResult<T>> results) {
46+
/**
47+
* Creates a new {@link SearchResults} instance from the given list of {@link SearchResult} items.
48+
*
49+
* @param results the search results to encapsulate, must not be {@code null}
50+
*/
51+
public SearchResults(List<? extends SearchResult<T>> results) {
4052
this.results = results;
4153
}
4254

4355
/**
44-
* Returns the actual content of the {@link SearchResult}s.
45-
*
46-
* @return the actual content.
56+
* Return the actual content of the {@link SearchResult} items as an unmodifiable list.
4757
*/
4858
public List<SearchResult<T>> getContent() {
4959
return Collections.unmodifiableList(results);
@@ -56,10 +66,33 @@ public Iterator<SearchResult<T>> iterator() {
5666
}
5767

5868
/**
59-
* Returns new {@link SearchResults} with the content of the current one mapped by the given {@link Function}.
69+
* Returns a sequential {@link Stream} containing {@link SearchResult} items in this {@code SearchResults} instance.
70+
*
71+
* @return a sequential {@link Stream} containing {@link SearchResult} items in this {@code SearchResults} instance.
72+
*/
73+
public Stream<SearchResult<T>> stream() {
74+
return Streamable.of(this).stream();
75+
}
76+
77+
/**
78+
* Returns a sequential {@link Stream} containing {@link #getContent() unwrapped content} items in this
79+
* {@code SearchResults} instance.
80+
*
81+
* @return a sequential {@link Stream} containing {@link #getContent() unwrapped content} items in this
82+
* {@code SearchResults} instance.
83+
*/
84+
public Stream<T> contentStream() {
85+
return getContent().stream().map(SearchResult::getContent);
86+
}
87+
88+
/**
89+
* Creates a new {@code SearchResults} instance with the content of the current results mapped via the given
90+
* {@link Function}.
6091
*
61-
* @param converter must not be {@literal null}.
62-
* @return a new {@link SearchResults} with the content of the current one mapped by the given {@link Function}.
92+
* @param converter the mapping function to apply to the content of each {@link SearchResult}, must not be
93+
* {@literal null}.
94+
* @param <U> the target type of the mapped content.
95+
* @return a new {@code SearchResults} instance containing mapped result content.
6396
*/
6497
public <U> SearchResults<U> map(Function<? super T, ? extends U> converter) {
6598

0 commit comments

Comments
 (0)