Skip to content

Commit 1645d6c

Browse files
marcingrzejszczakmp911de
authored andcommitted
Converted vector operations to search operations.
See #4706 Original pull request: #4882
1 parent 2b93bf3 commit 1645d6c

File tree

11 files changed

+146
-78
lines changed

11 files changed

+146
-78
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultIndexOperations.java

-7
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,9 @@
2424
import org.springframework.data.mongodb.MongoDatabaseFactory;
2525
import org.springframework.data.mongodb.UncategorizedMongoDbException;
2626
import org.springframework.data.mongodb.core.convert.QueryMapper;
27-
import org.springframework.data.mongodb.core.index.DefaultVectorIndexOperations;
2827
import org.springframework.data.mongodb.core.index.IndexDefinition;
2928
import org.springframework.data.mongodb.core.index.IndexInfo;
3029
import org.springframework.data.mongodb.core.index.IndexOperations;
31-
import org.springframework.data.mongodb.core.index.VectorIndexOperations;
3230
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
3331
import org.springframework.lang.Nullable;
3432
import org.springframework.util.Assert;
@@ -210,11 +208,6 @@ private List<IndexInfo> getIndexData(MongoCursor<Document> cursor) {
210208
});
211209
}
212210

213-
@Override
214-
public VectorIndexOperations vectorIndex() {
215-
return new DefaultVectorIndexOperations(mongoOperations, collectionName, type);
216-
}
217-
218211
@Nullable
219212
public <T> T execute(CollectionCallback<T> callback) {
220213

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,13 @@
8585
import org.springframework.data.mongodb.core.convert.MongoWriter;
8686
import org.springframework.data.mongodb.core.convert.QueryMapper;
8787
import org.springframework.data.mongodb.core.convert.UpdateMapper;
88+
import org.springframework.data.mongodb.core.index.DefaultSearchIndexOperations;
8889
import org.springframework.data.mongodb.core.index.IndexOperations;
8990
import org.springframework.data.mongodb.core.index.IndexOperationsProvider;
9091
import org.springframework.data.mongodb.core.index.MongoMappingEventPublisher;
9192
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator;
93+
import org.springframework.data.mongodb.core.index.SearchIndexOperations;
94+
import org.springframework.data.mongodb.core.index.SearchIndexOperationsProvider;
9295
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
9396
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
9497
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
@@ -183,7 +186,7 @@
183186
* @author Jakub Zurawa
184187
*/
185188
public class MongoTemplate
186-
implements MongoOperations, ApplicationContextAware, IndexOperationsProvider, ReadPreferenceAware {
189+
implements MongoOperations, ApplicationContextAware, IndexOperationsProvider, SearchIndexOperationsProvider, ReadPreferenceAware {
187190

188191
private static final Log LOGGER = LogFactory.getLog(MongoTemplate.class);
189192
private static final WriteResultChecking DEFAULT_WRITE_RESULT_CHECKING = WriteResultChecking.NONE;
@@ -3010,6 +3013,21 @@ static RuntimeException potentiallyConvertRuntimeException(RuntimeException ex,
30103013
return resolved == null ? ex : resolved;
30113014
}
30123015

3016+
@Override
3017+
public SearchIndexOperations searchIndexOps(String collectionName) {
3018+
return searchIndexOps(null, collectionName);
3019+
}
3020+
3021+
@Override
3022+
public SearchIndexOperations searchIndexOps(Class<?> type) {
3023+
return new DefaultSearchIndexOperations(this, type);
3024+
}
3025+
3026+
@Override
3027+
public SearchIndexOperations searchIndexOps(Class<?> type, String collectionName) {
3028+
return new DefaultSearchIndexOperations(this, collectionName, type);
3029+
}
3030+
30133031
// Callback implementations
30143032

30153033
/**
+10-10
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,23 @@
2626
import org.springframework.data.mongodb.core.aggregation.Aggregation;
2727
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
2828
import org.springframework.data.mongodb.core.convert.QueryMapper;
29-
import org.springframework.data.mongodb.core.index.VectorIndex.Filter;
29+
import org.springframework.data.mongodb.core.index.SearchIndex.Filter;
3030
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
3131
import org.springframework.lang.NonNull;
3232
import org.springframework.lang.Nullable;
3333

3434
/**
3535
* @author Christoph Strobl
3636
*/
37-
public class DefaultVectorIndexOperations extends DefaultIndexOperations implements VectorIndexOperations {
37+
public class DefaultSearchIndexOperations extends DefaultIndexOperations implements SearchIndexOperations {
3838

39-
private static final Log LOGGER = LogFactory.getLog(VectorIndexOperations.class);
39+
private static final Log LOGGER = LogFactory.getLog(SearchIndexOperations.class);
4040

41-
public DefaultVectorIndexOperations(MongoOperations mongoOperations, Class<?> type) {
41+
public DefaultSearchIndexOperations(MongoOperations mongoOperations, Class<?> type) {
4242
this(mongoOperations, mongoOperations.getCollectionName(type), type);
4343
}
4444

45-
public DefaultVectorIndexOperations(MongoOperations mongoOperations, String collectionName, @Nullable Class<?> type) {
45+
public DefaultSearchIndexOperations(MongoOperations mongoOperations, String collectionName, @Nullable Class<?> type) {
4646
super(mongoOperations, collectionName, type);
4747
}
4848

@@ -62,7 +62,7 @@ public boolean exists(String indexName) {
6262
}
6363

6464
@Override
65-
public void updateIndex(VectorIndex index) {
65+
public void updateIndex(SearchIndex index) {
6666

6767
MongoPersistentEntity<?> entity = lookupPersistentEntity(type, collectionName);
6868

@@ -106,10 +106,10 @@ public List<IndexInfo> getIndexInfo() {
106106
}
107107

108108
@Override
109-
public String ensureIndex(IndexDefinition indexDefinition) {
109+
public String ensureIndex(SearchIndexDefinition indexDefinition) {
110110

111-
if (!(indexDefinition instanceof VectorIndex vsi)) {
112-
return super.ensureIndex(indexDefinition);
111+
if (!(indexDefinition instanceof SearchIndex vsi)) {
112+
throw new IllegalStateException("Index definitions must be of type VectorIndex");
113113
}
114114

115115
MongoPersistentEntity<?> entity = lookupPersistentEntity(type, collectionName);
@@ -129,7 +129,7 @@ public String ensureIndex(IndexDefinition indexDefinition) {
129129
}
130130

131131
@NonNull
132-
private Document createIndexDocument(VectorIndex vsi, MongoPersistentEntity<?> entity) {
132+
private Document createIndexDocument(SearchIndex vsi, MongoPersistentEntity<?> entity) {
133133

134134
Document index = new Document(vsi.getIndexOptions());
135135
Document definition = new Document();

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOperations.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
* @author Christoph Strobl
2626
* @author Jens Schauder
2727
*/
28-
public interface IndexOperations extends VectorIndexOperationsProvider {
28+
public interface IndexOperations {
2929

3030
/**
3131
* Ensure that an index for the provided {@link IndexDefinition} exists for the collection indicated by the entity

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOperationsAdapter.java

-5
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ static IndexOperationsAdapter blocking(ReactiveIndexOperations reactiveIndexOper
4040

4141
return new IndexOperationsAdapter() {
4242

43-
@Override
44-
public VectorIndexOperations vectorIndex() {
45-
throw new IllegalStateException("currently not supported");
46-
}
47-
4843
@Override
4944
public String ensureIndex(IndexDefinition indexDefinition) {
5045
return reactiveIndexOperations.ensureIndex(indexDefinition).block();

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/VectorIndex.java renamed to spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/SearchIndex.java

+60-32
Original file line numberDiff line numberDiff line change
@@ -44,57 +44,58 @@
4444
*
4545
* @author Christoph Strobl
4646
*/
47-
public class VectorIndex implements IndexDefinition {
47+
public class SearchIndex implements SearchIndexDefinition {
4848

4949
private final String name;
5050
private String path;
5151
private int dimensions;
5252
private String similarity;
5353
private List<Filter> filters;
54+
private String quantization = Quantization.NONE.name();
5455

5556
/**
56-
* Create a new {@link VectorIndex} instance.
57+
* Create a new {@link SearchIndex} instance.
5758
*
5859
* @param name The name of the index.
5960
*/
60-
public VectorIndex(String name) {
61+
public SearchIndex(String name) {
6162
this.name = name;
6263
}
6364

6465
/**
65-
* Create a new {@link VectorIndex} instance using similarity based on the angle between vectors.
66+
* Create a new {@link SearchIndex} instance using similarity based on the angle between vectors.
6667
*
6768
* @param name The name of the index.
68-
* @return new instance of {@link VectorIndex}.
69+
* @return new instance of {@link SearchIndex}.
6970
*/
70-
public static VectorIndex cosine(String name) {
71+
public static SearchIndex cosine(String name) {
7172

72-
VectorIndex idx = new VectorIndex(name);
73+
SearchIndex idx = new SearchIndex(name);
7374
return idx.similarity(SimilarityFunction.COSINE);
7475
}
7576

7677
/**
77-
* Create a new {@link VectorIndex} instance using similarity based the distance between vector ends.
78+
* Create a new {@link SearchIndex} instance using similarity based the distance between vector ends.
7879
*
7980
* @param name The name of the index.
80-
* @return new instance of {@link VectorIndex}.
81+
* @return new instance of {@link SearchIndex}.
8182
*/
82-
public static VectorIndex euclidean(String name) {
83+
public static SearchIndex euclidean(String name) {
8384

84-
VectorIndex idx = new VectorIndex(name);
85+
SearchIndex idx = new SearchIndex(name);
8586
return idx.similarity(SimilarityFunction.EUCLIDEAN);
8687
}
8788

8889
/**
89-
* Create a new {@link VectorIndex} instance using similarity based on based on both angle and magnitude of the
90+
* Create a new {@link SearchIndex} instance using similarity based on based on both angle and magnitude of the
9091
* vectors.
9192
*
9293
* @param name The name of the index.
93-
* @return new instance of {@link VectorIndex}.
94+
* @return new instance of {@link SearchIndex}.
9495
*/
95-
public static VectorIndex dotProduct(String name) {
96+
public static SearchIndex dotProduct(String name) {
9697

97-
VectorIndex idx = new VectorIndex(name);
98+
SearchIndex idx = new SearchIndex(name);
9899
return idx.similarity(SimilarityFunction.DOT_PRODUCT);
99100
}
100101

@@ -104,7 +105,7 @@ public static VectorIndex dotProduct(String name) {
104105
* @param path The path using dot notation.
105106
* @return this.
106107
*/
107-
public VectorIndex path(String path) {
108+
public SearchIndex path(String path) {
108109

109110
this.path = path;
110111
return this;
@@ -116,7 +117,7 @@ public VectorIndex path(String path) {
116117
* @param dimensions value between {@code 0} and {@code 4096}.
117118
* @return this.
118119
*/
119-
public VectorIndex dimensions(int dimensions) {
120+
public SearchIndex dimensions(int dimensions) {
120121
this.dimensions = dimensions;
121122
return this;
122123
}
@@ -129,7 +130,7 @@ public VectorIndex dimensions(int dimensions) {
129130
* @see SimilarityFunction
130131
* @see #similarity(SimilarityFunction)
131132
*/
132-
public VectorIndex similarity(String similarity) {
133+
public SearchIndex similarity(String similarity) {
133134
this.similarity = similarity;
134135
return this;
135136
}
@@ -140,17 +141,41 @@ public VectorIndex similarity(String similarity) {
140141
* @param similarity must not be {@literal null}.
141142
* @return this.
142143
*/
143-
public VectorIndex similarity(SimilarityFunction similarity) {
144+
public SearchIndex similarity(SimilarityFunction similarity) {
144145
return similarity(similarity.getFunctionName());
145146
}
146147

148+
149+
/**
150+
* Quantization used.
151+
*
152+
* @param quantization should be one of {@literal none | scalar | binary}.
153+
* @return this.
154+
* @see Quantization
155+
* @see #quantization(Quantization)
156+
*/
157+
public SearchIndex quantization(String quantization) {
158+
this.quantization = quantization;
159+
return this;
160+
}
161+
162+
/**
163+
* Quntization used.
164+
*
165+
* @param quantization must not be {@literal null}.
166+
* @return this.
167+
*/
168+
public SearchIndex quantization(Quantization quantization) {
169+
return similarity(quantization.getQuantizationName());
170+
}
171+
147172
/**
148173
* Add a {@link Filter} that can be used to narrow search scope.
149174
*
150175
* @param filter must not be {@literal null}.
151176
* @return this.
152177
*/
153-
public VectorIndex filter(Filter filter) {
178+
public SearchIndex filter(Filter filter) {
154179

155180
if (this.filters == null) {
156181
this.filters = new ArrayList<>(3);
@@ -167,21 +192,10 @@ public VectorIndex filter(Filter filter) {
167192
* @return this.
168193
* @see #filter(Filter)
169194
*/
170-
public VectorIndex filter(String path) {
195+
public SearchIndex filter(String path) {
171196
return filter(new Filter(path));
172197
}
173198

174-
@Override
175-
public Document getIndexKeys() {
176-
177-
// List<Document> fields = new ArrayList<>(filters.size()+1);
178-
// fields.
179-
180-
// needs to be wrapped in new Document("definition", before sending to server
181-
// return new Document("fields", fields);
182-
return new Document();
183-
}
184-
185199
@Override
186200
public Document getIndexOptions() {
187201
return new Document("name", name).append("type", "vectorSearch");
@@ -224,4 +238,18 @@ public String getFunctionName() {
224238
return functionName;
225239
}
226240
}
241+
242+
public enum Quantization {
243+
NONE("none"), SCALAR("scalar"), BINARY("binary");
244+
245+
String quantizationName;
246+
247+
Quantization(String quantizationName) {
248+
this.quantizationName = quantizationName;
249+
}
250+
251+
public String getQuantizationName() {
252+
return quantizationName;
253+
}
254+
}
227255
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2011-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mongodb.core.index;
17+
18+
import org.bson.Document;
19+
20+
/**
21+
* @author Marcin Grzejszczak
22+
*/
23+
public interface SearchIndexDefinition {
24+
25+
/**
26+
* Get the index properties such as {@literal unique},...
27+
*
28+
* @return never {@literal null}.
29+
*/
30+
Document getIndexOptions();
31+
}
+3-3
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
/**
2121
* @author Christoph Strobl
2222
*/
23-
public interface VectorIndexOperations {
23+
public interface SearchIndexOperations {
2424

25-
String ensureIndex(IndexDefinition indexDefinition);
25+
String ensureIndex(SearchIndexDefinition indexDefinition);
2626

27-
void updateIndex(VectorIndex index);
27+
void updateIndex(SearchIndex index);
2828

2929
boolean exists(String indexName);
3030

Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
/**
1919
* @author Christoph Strobl
2020
*/
21-
public interface VectorIndexOperationsProvider {
21+
public interface SearchIndexOperationsProvider {
2222

23-
VectorIndexOperations vectorIndex();
23+
SearchIndexOperations searchIndexOps(String collectionName);
2424

25+
SearchIndexOperations searchIndexOps(Class<?> type);
26+
27+
SearchIndexOperations searchIndexOps(Class<?> type, String collectionName);
2528
}

0 commit comments

Comments
 (0)