使用 Spring-Boot 3 和 Hibernate 6 在 PostgreSQL 数据库中支持 pgvector 向量扩展的最佳方法是什么,这样我就可以使用 JPA 实体创建向量嵌入?
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(5));
虽然我确实找到了适用于以前的 Hibernate 版本的解决方案,但它们不适用于 Hibernate 6,因为它需要 jakarta.persistence.* 包而不是 javax.persistence.*。我尝试使用自定义转换器类,但这没有成功(而且我什至不确定这是否是正确的方向):
项目.java
import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.TypeAlias;
import java.util.List;
@Data
@NoArgsConstructor
@Entity
@Table(name = "items")
@JsonInclude(JsonInclude.Include.NON_NULL)
@TypeAlias("json")
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Convert(converter = VectorConverter.class)
@Column(columnDefinition = "vector(5)")
private List<Double> embedding;
}
VectorConverter.java:
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import java.util.ArrayList;
import java.util.List;
@Converter
public class VectorConverter implements AttributeConverter<List<Double>, String> {
@Override
public String convertToDatabaseColumn(List<Double> attribute) {
if (attribute == null || attribute.isEmpty()) {
return "'[]'";
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[");
for (int i = 0; i < attribute.size(); i++) {
stringBuilder.append(attribute.get(i));
if (i < attribute.size() - 1) {
stringBuilder.append(",");
}
}
stringBuilder.append("]");
return stringBuilder.toString();
}
public List<Double> convertToEntityAttribute(String dbData) {
if (dbData == null || dbData.isEmpty()) {
return new ArrayList<>();
}
String[] values = dbData.substring(1, dbData.length() - 1).split(",");
List<Double> embeddingList = new ArrayList<>();
for (String value : values) {
embeddingList.add(Double.valueOf(value.trim()));
}
return embeddingList;
}
}
导致以下错误:
Hint: You will need to rewrite or cast the expression.
Position: 39] [insert into items (embedding) values (?)]; SQL [insert into items (embedding) values (?)]] with root cause
org.postgresql.util.PSQLException: ERROR: column "embedding" is of type vector but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 39
从 6.4 开始,我认为 Hibernate 发布了一个向量模块:https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#vector-module
您导入 hibernate-vector 库(您不再需要转换器),然后这应该可以工作:
@Column( name = "the_vector" )
@JdbcTypeCode(SqlTypes.VECTOR)
@Array(length = 3)
private float[] theVector;