Skip to content

Commit be22692

Browse files
committed
Coherence vector store builder refactoring
1 parent 8877672 commit be22692

File tree

4 files changed

+172
-23
lines changed

4 files changed

+172
-23
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.ai.vectorstore;
17+
package org.springframework.ai.vectorstore.coherence;
1818

1919
import java.util.List;
2020

Lines changed: 159 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.ai.vectorstore;
17+
package org.springframework.ai.vectorstore.coherence;
1818

1919
import java.util.ArrayList;
2020
import java.util.HashMap;
@@ -39,8 +39,15 @@
3939
import org.springframework.ai.document.Document;
4040
import org.springframework.ai.document.DocumentMetadata;
4141
import org.springframework.ai.embedding.EmbeddingModel;
42+
import org.springframework.ai.observation.conventions.VectorStoreProvider;
43+
import org.springframework.ai.vectorstore.AbstractVectorStoreBuilder;
44+
import org.springframework.ai.vectorstore.SearchRequest;
4245
import org.springframework.ai.vectorstore.filter.Filter.Expression;
46+
import org.springframework.ai.vectorstore.observation.AbstractObservationVectorStore;
47+
import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext;
4348
import org.springframework.beans.factory.InitializingBean;
49+
import org.springframework.util.Assert;
50+
import org.springframework.util.StringUtils;
4451

4552
/**
4653
* <p>
@@ -66,7 +73,7 @@
6673
* @author Thomas Vitale
6774
* @since 1.0.0
6875
*/
69-
public class CoherenceVectorStore implements VectorStore, InitializingBean {
76+
public class CoherenceVectorStore extends AbstractObservationVectorStore implements InitializingBean {
7077

7178
public enum IndexType {
7279

@@ -112,11 +119,6 @@ public enum DistanceType {
112119

113120
public static final CoherenceFilterExpressionConverter FILTER_EXPRESSION_CONVERTER = new CoherenceFilterExpressionConverter();
114121

115-
/**
116-
* The embedding model to use to create query embedding.
117-
*/
118-
private final EmbeddingModel embeddingModel;
119-
120122
private final int dimensions;
121123

122124
private final Session session;
@@ -126,45 +128,92 @@ public enum DistanceType {
126128
/**
127129
* Map name where vectors will be stored.
128130
*/
129-
private String mapName = DEFAULT_MAP_NAME;
131+
private String mapName;
130132

131133
/**
132134
* Distance type to use for computing vector distances.
133135
*/
134-
private DistanceType distanceType = DEFAULT_DISTANCE_TYPE;
136+
private DistanceType distanceType;
135137

136138
private boolean forcedNormalization;
137139

138-
private IndexType indexType = IndexType.NONE;
140+
private IndexType indexType;
139141

142+
/**
143+
* Creates a new CoherenceVectorStore with minimal configuration.
144+
* @param embeddingModel the embedding model to use
145+
* @param session the Coherence session
146+
* @deprecated Since 1.0.0-M5, use {@link #builder()} instead
147+
*/
148+
@Deprecated(since = "1.0.0-M5", forRemoval = true)
140149
public CoherenceVectorStore(EmbeddingModel embeddingModel, Session session) {
141-
this.embeddingModel = embeddingModel;
142-
this.session = session;
143-
this.dimensions = embeddingModel.dimensions();
150+
this(builder().embeddingModel(embeddingModel).session(session));
151+
}
152+
153+
/**
154+
* Protected constructor that accepts a builder instance. This is the preferred way to
155+
* create new CoherenceVectorStore instances.
156+
* @param builder the configured builder instance
157+
*/
158+
protected CoherenceVectorStore(CoherenceBuilder builder) {
159+
super(builder);
160+
161+
Assert.notNull(builder.session, "Session must not be null");
162+
163+
this.session = builder.session;
164+
this.dimensions = builder.getEmbeddingModel().dimensions();
165+
this.mapName = builder.mapName;
166+
this.distanceType = builder.distanceType;
167+
this.forcedNormalization = builder.forcedNormalization;
168+
this.indexType = builder.indexType;
169+
}
170+
171+
/**
172+
* Creates a new builder for configuring and creating CoherenceVectorStore instances.
173+
* @return a new builder instance
174+
*/
175+
public static CoherenceBuilder builder() {
176+
return new CoherenceBuilder();
144177
}
145178

179+
/**
180+
* @deprecated Since 1.0.0-M5, use {@link #builder()} instead
181+
*/
182+
@Deprecated(since = "1.0.0-M5", forRemoval = true)
146183
public CoherenceVectorStore setMapName(String mapName) {
147184
this.mapName = mapName;
148185
return this;
149186
}
150187

188+
/**
189+
* @deprecated Since 1.0.0-M5, use {@link #builder()} instead
190+
*/
191+
@Deprecated(since = "1.0.0-M5", forRemoval = true)
151192
public CoherenceVectorStore setDistanceType(DistanceType distanceType) {
152193
this.distanceType = distanceType;
153194
return this;
154195
}
155196

197+
/**
198+
* @deprecated Since 1.0.0-M5, use {@link #builder()} instead
199+
*/
200+
@Deprecated(since = "1.0.0-M5", forRemoval = true)
156201
public CoherenceVectorStore setIndexType(IndexType indexType) {
157202
this.indexType = indexType;
158203
return this;
159204
}
160205

206+
/**
207+
* @deprecated Since 1.0.0-M5, use {@link #builder()} instead
208+
*/
209+
@Deprecated(since = "1.0.0-M5", forRemoval = true)
161210
public CoherenceVectorStore setForcedNormalization(boolean forcedNormalization) {
162211
this.forcedNormalization = forcedNormalization;
163212
return this;
164213
}
165214

166215
@Override
167-
public void add(final List<Document> documents) {
216+
public void doAdd(final List<Document> documents) {
168217
Map<DocumentChunk.Id, DocumentChunk> chunks = new HashMap<>((int) Math.ceil(documents.size() / 0.75f));
169218
for (Document doc : documents) {
170219
var id = toChunkId(doc.getId());
@@ -176,7 +225,7 @@ public void add(final List<Document> documents) {
176225
}
177226

178227
@Override
179-
public Optional<Boolean> delete(final List<String> idList) {
228+
public Optional<Boolean> doDelete(final List<String> idList) {
180229
var chunkIds = idList.stream().map(this::toChunkId).toList();
181230
Map<DocumentChunk.Id, Boolean> results = this.documentChunks.invokeAll(chunkIds, entry -> {
182231
if (entry.isPresent()) {
@@ -194,7 +243,7 @@ public Optional<Boolean> delete(final List<String> idList) {
194243
}
195244

196245
@Override
197-
public List<Document> similaritySearch(SearchRequest request) {
246+
public List<Document> doSimilaritySearch(SearchRequest request) {
198247
// From the provided query, generate a vector using the embedding model
199248
final Float32Vector vector = toFloat32Vector(this.embeddingModel.embed(request.getQuery()));
200249

@@ -265,4 +314,98 @@ String getMapName() {
265314
return this.mapName;
266315
}
267316

317+
@Override
318+
public VectorStoreObservationContext.Builder createObservationContextBuilder(String operationName) {
319+
320+
return VectorStoreObservationContext.builder(VectorStoreProvider.NEO4J.value(), operationName)
321+
.withCollectionName(this.mapName)
322+
.withDimensions(this.embeddingModel.dimensions());
323+
}
324+
325+
/**
326+
* Builder class for creating {@link CoherenceVectorStore} instances.
327+
* <p>
328+
* Provides a fluent API for configuring all aspects of the Coherence vector store,
329+
* including map name, distance type, and indexing options.
330+
*
331+
* @since 1.0.0
332+
*/
333+
public static class CoherenceBuilder extends AbstractVectorStoreBuilder<CoherenceBuilder> {
334+
335+
private Session session;
336+
337+
private String mapName = DEFAULT_MAP_NAME;
338+
339+
private DistanceType distanceType = DEFAULT_DISTANCE_TYPE;
340+
341+
private boolean forcedNormalization = false;
342+
343+
private IndexType indexType = IndexType.NONE;
344+
345+
/**
346+
* Sets the Coherence session.
347+
* @param session the session to use
348+
* @return the builder instance
349+
* @throws IllegalArgumentException if session is null
350+
*/
351+
public CoherenceBuilder session(Session session) {
352+
Assert.notNull(session, "Session must not be null");
353+
this.session = session;
354+
return this;
355+
}
356+
357+
/**
358+
* Sets the map name for vector storage.
359+
* @param mapName the name of the map to use
360+
* @return the builder instance
361+
*/
362+
public CoherenceBuilder mapName(String mapName) {
363+
if (StringUtils.hasText(mapName)) {
364+
this.mapName = mapName;
365+
}
366+
return this;
367+
}
368+
369+
/**
370+
* Sets the distance type for vector similarity calculations.
371+
* @param distanceType the distance type to use
372+
* @return the builder instance
373+
* @throws IllegalArgumentException if distanceType is null
374+
*/
375+
public CoherenceBuilder distanceType(DistanceType distanceType) {
376+
Assert.notNull(distanceType, "DistanceType must not be null");
377+
this.distanceType = distanceType;
378+
return this;
379+
}
380+
381+
/**
382+
* Sets whether to force vector normalization.
383+
* @param forcedNormalization true to force normalization, false otherwise
384+
* @return the builder instance
385+
*/
386+
public CoherenceBuilder forcedNormalization(boolean forcedNormalization) {
387+
this.forcedNormalization = forcedNormalization;
388+
return this;
389+
}
390+
391+
/**
392+
* Sets the index type for vector storage.
393+
* @param indexType the index type to use
394+
* @return the builder instance
395+
* @throws IllegalArgumentException if indexType is null
396+
*/
397+
public CoherenceBuilder indexType(IndexType indexType) {
398+
Assert.notNull(indexType, "IndexType must not be null");
399+
this.indexType = indexType;
400+
return this;
401+
}
402+
403+
@Override
404+
public CoherenceVectorStore build() {
405+
validate();
406+
return new CoherenceVectorStore(this);
407+
}
408+
409+
}
410+
268411
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.ai.vectorstore;
17+
package org.springframework.ai.vectorstore.coherence;
1818

1919
import com.tangosol.util.Filters;
2020
import com.tangosol.util.ValueExtractor;
Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.ai.vectorstore;
17+
package org.springframework.ai.vectorstore.coherence;
1818

1919
import java.io.IOException;
2020
import java.nio.charset.StandardCharsets;
@@ -50,6 +50,8 @@
5050
import org.springframework.ai.document.DocumentMetadata;
5151
import org.springframework.ai.embedding.EmbeddingModel;
5252
import org.springframework.ai.transformers.TransformersEmbeddingModel;
53+
import org.springframework.ai.vectorstore.SearchRequest;
54+
import org.springframework.ai.vectorstore.VectorStore;
5355
import org.springframework.ai.vectorstore.filter.FilterExpressionTextParser;
5456
import org.springframework.beans.factory.annotation.Value;
5557
import org.springframework.boot.SpringBootConfiguration;
@@ -309,10 +311,14 @@ public static class TestClient {
309311

310312
@Bean
311313
public VectorStore vectorStore(EmbeddingModel embeddingModel, Session session) {
312-
return new CoherenceVectorStore(embeddingModel, session).setDistanceType(this.distanceType)
313-
.setIndexType(this.indexType)
314-
.setForcedNormalization(this.distanceType == CoherenceVectorStore.DistanceType.COSINE
315-
|| this.distanceType == CoherenceVectorStore.DistanceType.IP);
314+
return CoherenceVectorStore.builder()
315+
.embeddingModel(embeddingModel)
316+
.session(session)
317+
.distanceType(this.distanceType)
318+
.indexType(this.indexType)
319+
.forcedNormalization(this.distanceType == CoherenceVectorStore.DistanceType.COSINE
320+
|| this.distanceType == CoherenceVectorStore.DistanceType.IP)
321+
.build();
316322
}
317323

318324
@Bean

0 commit comments

Comments
 (0)