35
35
36
36
import org .springframework .ai .document .Document ;
37
37
import org .springframework .ai .document .DocumentMetadata ;
38
- import org .springframework .ai .embedding .BatchingStrategy ;
39
38
import org .springframework .ai .embedding .EmbeddingModel ;
40
39
import org .springframework .ai .embedding .EmbeddingOptionsBuilder ;
41
- import org .springframework .ai .embedding .TokenCountBatchingStrategy ;
42
40
import org .springframework .ai .observation .conventions .VectorStoreProvider ;
43
41
import org .springframework .ai .observation .conventions .VectorStoreSimilarityMetric ;
44
42
import org .springframework .ai .util .JacksonUtils ;
153
151
* @author Thomas Vitale
154
152
* @author Soby Chacko
155
153
* @author Sebastien Deleuze
154
+ * @author Jihoon Kim
156
155
* @since 1.0.0
157
156
*/
158
157
public class PgVectorStore extends AbstractObservationVectorStore implements InitializingBean {
@@ -163,6 +162,8 @@ public class PgVectorStore extends AbstractObservationVectorStore implements Ini
163
162
164
163
public static final String DEFAULT_TABLE_NAME = "vector_store" ;
165
164
165
+ public static final PgIdType DEFAULT_ID_TYPE = PgIdType .UUID ;
166
+
166
167
public static final String DEFAULT_VECTOR_INDEX_NAME = "spring_ai_vector_index" ;
167
168
168
169
public static final String DEFAULT_SCHEMA_NAME = "public" ;
@@ -188,6 +189,8 @@ public class PgVectorStore extends AbstractObservationVectorStore implements Ini
188
189
189
190
private final String schemaName ;
190
191
192
+ private final PgIdType idType ;
193
+
191
194
private final boolean schemaValidation ;
192
195
193
196
private final boolean initializeSchema ;
@@ -225,6 +228,7 @@ protected PgVectorStore(PgVectorStoreBuilder builder) {
225
228
: this .vectorTableName + "_index" ;
226
229
227
230
this .schemaName = builder .schemaName ;
231
+ this .idType = builder .idType ;
228
232
this .schemaValidation = builder .vectorTableValidationsEnabled ;
229
233
230
234
this .jdbcTemplate = builder .jdbcTemplate ;
@@ -273,13 +277,13 @@ private void insertOrUpdateBatch(List<Document> batch, List<Document> documents,
273
277
public void setValues (PreparedStatement ps , int i ) throws SQLException {
274
278
275
279
var document = batch .get (i );
280
+ var id = convertIdToPgType (document .getId ());
276
281
var content = document .getText ();
277
282
var json = toJson (document .getMetadata ());
278
283
var embedding = embeddings .get (documents .indexOf (document ));
279
284
var pGvector = new PGvector (embedding );
280
285
281
- StatementCreatorUtils .setParameterValue (ps , 1 , SqlTypeValue .TYPE_UNKNOWN ,
282
- UUID .fromString (document .getId ()));
286
+ StatementCreatorUtils .setParameterValue (ps , 1 , SqlTypeValue .TYPE_UNKNOWN , id );
283
287
StatementCreatorUtils .setParameterValue (ps , 2 , SqlTypeValue .TYPE_UNKNOWN , content );
284
288
StatementCreatorUtils .setParameterValue (ps , 3 , SqlTypeValue .TYPE_UNKNOWN , json );
285
289
StatementCreatorUtils .setParameterValue (ps , 4 , SqlTypeValue .TYPE_UNKNOWN , pGvector );
@@ -304,6 +308,19 @@ private String toJson(Map<String, Object> map) {
304
308
}
305
309
}
306
310
311
+ private Object convertIdToPgType (String id ) {
312
+ if (this .initializeSchema ) {
313
+ return UUID .fromString (id );
314
+ }
315
+
316
+ return switch (getIdType ()) {
317
+ case UUID -> UUID .fromString (id );
318
+ case TEXT -> id ;
319
+ case INTEGER , SERIAL -> Integer .valueOf (id );
320
+ case BIGSERIAL -> Long .valueOf (id );
321
+ };
322
+ }
323
+
307
324
@ Override
308
325
public Optional <Boolean > doDelete (List <String > idList ) {
309
326
int updateCount = 0 ;
@@ -429,6 +446,10 @@ private String getFullyQualifiedTableName() {
429
446
return this .schemaName + "." + this .vectorTableName ;
430
447
}
431
448
449
+ private PgIdType getIdType () {
450
+ return this .idType ;
451
+ }
452
+
432
453
private String getVectorTableName () {
433
454
return this .vectorTableName ;
434
455
}
@@ -513,6 +534,12 @@ public enum PgIndexType {
513
534
514
535
}
515
536
537
+ public enum PgIdType {
538
+
539
+ UUID , TEXT , INTEGER , SERIAL , BIGSERIAL
540
+
541
+ }
542
+
516
543
/**
517
544
* Defaults to CosineDistance. But if vectors are normalized to length 1 (like OpenAI
518
545
* embeddings), use inner product (NegativeInnerProduct) for best performance.
@@ -608,6 +635,8 @@ public static final class PgVectorStoreBuilder extends AbstractVectorStoreBuilde
608
635
609
636
private String vectorTableName = PgVectorStore .DEFAULT_TABLE_NAME ;
610
637
638
+ private PgIdType idType = PgVectorStore .DEFAULT_ID_TYPE ;
639
+
611
640
private boolean vectorTableValidationsEnabled = PgVectorStore .DEFAULT_SCHEMA_VALIDATION ;
612
641
613
642
private int dimensions = PgVectorStore .INVALID_EMBEDDING_DIMENSION ;
@@ -638,6 +667,11 @@ public PgVectorStoreBuilder vectorTableName(String vectorTableName) {
638
667
return this ;
639
668
}
640
669
670
+ public PgVectorStoreBuilder idType (PgIdType idType ) {
671
+ this .idType = idType ;
672
+ return this ;
673
+ }
674
+
641
675
public PgVectorStoreBuilder vectorTableValidationsEnabled (boolean vectorTableValidationsEnabled ) {
642
676
this .vectorTableValidationsEnabled = vectorTableValidationsEnabled ;
643
677
return this ;
0 commit comments