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 ;
152
150
* @author Thomas Vitale
153
151
* @author Soby Chacko
154
152
* @author Sebastien Deleuze
153
+ * @author Jihoon Kim
155
154
* @since 1.0.0
156
155
*/
157
156
public class PgVectorStore extends AbstractObservationVectorStore implements InitializingBean {
@@ -162,6 +161,8 @@ public class PgVectorStore extends AbstractObservationVectorStore implements Ini
162
161
163
162
public static final String DEFAULT_TABLE_NAME = "vector_store" ;
164
163
164
+ public static final PgIdType DEFAULT_ID_TYPE = PgIdType .UUID ;
165
+
165
166
public static final String DEFAULT_VECTOR_INDEX_NAME = "spring_ai_vector_index" ;
166
167
167
168
public static final String DEFAULT_SCHEMA_NAME = "public" ;
@@ -187,6 +188,8 @@ public class PgVectorStore extends AbstractObservationVectorStore implements Ini
187
188
188
189
private final String schemaName ;
189
190
191
+ private final PgIdType idType ;
192
+
190
193
private final boolean schemaValidation ;
191
194
192
195
private final boolean initializeSchema ;
@@ -224,6 +227,7 @@ protected PgVectorStore(PgVectorStoreBuilder builder) {
224
227
: this .vectorTableName + "_index" ;
225
228
226
229
this .schemaName = builder .schemaName ;
230
+ this .idType = builder .idType ;
227
231
this .schemaValidation = builder .vectorTableValidationsEnabled ;
228
232
229
233
this .jdbcTemplate = builder .jdbcTemplate ;
@@ -272,13 +276,13 @@ private void insertOrUpdateBatch(List<Document> batch, List<Document> documents,
272
276
public void setValues (PreparedStatement ps , int i ) throws SQLException {
273
277
274
278
var document = batch .get (i );
279
+ var id = convertIdToPgType (document .getId ());
275
280
var content = document .getText ();
276
281
var json = toJson (document .getMetadata ());
277
282
var embedding = embeddings .get (documents .indexOf (document ));
278
283
var pGvector = new PGvector (embedding );
279
284
280
- StatementCreatorUtils .setParameterValue (ps , 1 , SqlTypeValue .TYPE_UNKNOWN ,
281
- UUID .fromString (document .getId ()));
285
+ StatementCreatorUtils .setParameterValue (ps , 1 , SqlTypeValue .TYPE_UNKNOWN , id );
282
286
StatementCreatorUtils .setParameterValue (ps , 2 , SqlTypeValue .TYPE_UNKNOWN , content );
283
287
StatementCreatorUtils .setParameterValue (ps , 3 , SqlTypeValue .TYPE_UNKNOWN , json );
284
288
StatementCreatorUtils .setParameterValue (ps , 4 , SqlTypeValue .TYPE_UNKNOWN , pGvector );
@@ -303,6 +307,19 @@ private String toJson(Map<String, Object> map) {
303
307
}
304
308
}
305
309
310
+ private Object convertIdToPgType (String id ) {
311
+ if (this .initializeSchema ) {
312
+ return UUID .fromString (id );
313
+ }
314
+
315
+ return switch (getIdType ()) {
316
+ case UUID -> UUID .fromString (id );
317
+ case TEXT -> id ;
318
+ case INTEGER , SERIAL -> Integer .valueOf (id );
319
+ case BIGSERIAL -> Long .valueOf (id );
320
+ };
321
+ }
322
+
306
323
@ Override
307
324
public Optional <Boolean > doDelete (List <String > idList ) {
308
325
int updateCount = 0 ;
@@ -412,6 +429,10 @@ private String getFullyQualifiedTableName() {
412
429
return this .schemaName + "." + this .vectorTableName ;
413
430
}
414
431
432
+ private PgIdType getIdType () {
433
+ return this .idType ;
434
+ }
435
+
415
436
private String getVectorTableName () {
416
437
return this .vectorTableName ;
417
438
}
@@ -489,6 +510,12 @@ public enum PgIndexType {
489
510
490
511
}
491
512
513
+ public enum PgIdType {
514
+
515
+ UUID , TEXT , INTEGER , SERIAL , BIGSERIAL
516
+
517
+ }
518
+
492
519
/**
493
520
* Defaults to CosineDistance. But if vectors are normalized to length 1 (like OpenAI
494
521
* embeddings), use inner product (NegativeInnerProduct) for best performance.
@@ -584,6 +611,8 @@ public static final class PgVectorStoreBuilder extends AbstractVectorStoreBuilde
584
611
585
612
private String vectorTableName = PgVectorStore .DEFAULT_TABLE_NAME ;
586
613
614
+ private PgIdType idType = PgVectorStore .DEFAULT_ID_TYPE ;
615
+
587
616
private boolean vectorTableValidationsEnabled = PgVectorStore .DEFAULT_SCHEMA_VALIDATION ;
588
617
589
618
private int dimensions = PgVectorStore .INVALID_EMBEDDING_DIMENSION ;
@@ -614,6 +643,11 @@ public PgVectorStoreBuilder vectorTableName(String vectorTableName) {
614
643
return this ;
615
644
}
616
645
646
+ public PgVectorStoreBuilder idType (PgIdType idType ) {
647
+ this .idType = idType ;
648
+ return this ;
649
+ }
650
+
617
651
public PgVectorStoreBuilder vectorTableValidationsEnabled (boolean vectorTableValidationsEnabled ) {
618
652
this .vectorTableValidationsEnabled = vectorTableValidationsEnabled ;
619
653
return this ;
0 commit comments