1414 * limitations under the License.
1515 */
1616
17- package org .springframework .ai .vectorstore ;
17+ package org .springframework .ai .vectorstore . coherence ;
1818
1919import java .util .ArrayList ;
2020import java .util .HashMap ;
3939import org .springframework .ai .document .Document ;
4040import org .springframework .ai .document .DocumentMetadata ;
4141import 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 ;
4245import org .springframework .ai .vectorstore .filter .Filter .Expression ;
46+ import org .springframework .ai .vectorstore .observation .AbstractObservationVectorStore ;
47+ import org .springframework .ai .vectorstore .observation .VectorStoreObservationContext ;
4348import org .springframework .beans .factory .InitializingBean ;
49+ import org .springframework .util .Assert ;
50+ import org .springframework .util .StringUtils ;
4451
4552/**
4653 * <p>
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}
0 commit comments