英文:
What JPA + Hibernate data type should I use to support the vector extension in a PostgreSQL database?
问题
JPA + Hibernate数据类型应该使用PostgreSQL数据库中的vector
扩展来支持,以便允许您在JPA实体中创建嵌入向量。
英文:
What JPA + Hibernate data type should I use to support the vector extension in a PostgreSQL database, so that it allows me to create embeddings using a JPA Entity?
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
答案1
得分: 3
你可以使用vladmihalcea的Hibernate类型将向量类型转换为List
-
在pom.xml文件中添加依赖:
<dependency> <groupId>io.hypersistence</groupId> <artifactId>hypersistence-utils-hibernate-55</artifactId> <version>3.5.0</version> </dependency>
-
创建Item类:
import com.fasterxml.jackson.annotation.JsonInclude; import io.hypersistence.utils.hibernate.type.json.JsonType; import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import javax.persistence.*; import java.util.List; @Data @NoArgsConstructor @Entity @Table(name = "items") @JsonInclude(JsonInclude.Include.NON_NULL) @TypeDef(name = "json", typeClass = JsonType.class) public class Item { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Type(type = "json") @Column(columnDefinition = "vector") private List<Double> embedding; }
-
创建支持保存和查找的JpaRepository接口。您可以使用原生SQL编写自定义的findNearestNeighbors方法。
import org.springframework.data.jpa.repository.JpaRepository; public interface ItemRepository extends JpaRepository<Item, Long> { // 通过向量查找最近的邻居,例如 value = "[1,2,3]" // 这也可以工作,强制转换等同于postgresql中的::运算符 //@Query(nativeQuery = true, value = "SELECT * FROM items ORDER BY embedding <-> cast(? as vector) LIMIT 5") @Query(nativeQuery = true, value = "SELECT * FROM items ORDER BY embedding <-> ?\\:\\:vector LIMIT 5") List<Item> findNearestNeighbors(String value); // 通过同一表中的记录查找最近的邻居 @Query(nativeQuery = true, value = "SELECT * FROM items WHERE id != :id ORDER BY embedding <-> (SELECT embedding FROM items WHERE id = :id) LIMIT 5") List<Item> findNearestNeighbors(Long id); }
-
测试创建、查询和findNearestNeighbors:
@Autowired private ItemRepository itemRepository; @Test @Rollback(false) @Transactional public void createItem() { Item item = new Item(); Random rand = new Random(); List<Double> embedding = new ArrayList<>(); for (int i = 0; i < 3; i++) embedding.add(rand.nextDouble()); item.setEmbedding(embedding); itemRepository.save(item); } @Test public void loadItems() { final List<Item> items = itemRepository.findAll(); System.out.println(items); } @Test public void findNearestNeighbors() { final String value = "[0.1, 0.2, 0.3]"; final List<Item> items = itemRepository.findNearestNeighbors(value); System.out.println(items); }
英文:
You can use vladmihalcea Hibernate types to convert a vector type to List<Double>, so it is possible to save or query with JpaRepository.
-
Add a dependency to the pom.xml file:
<dependency> <groupId>io.hypersistence</groupId> <artifactId>hypersistence-utils-hibernate-55</artifactId> <version>3.5.0</version> </dependency>
-
Create the Item class:
import com.fasterxml.jackson.annotation.JsonInclude; import io.hypersistence.utils.hibernate.type.json.JsonType; import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import javax.persistence.*; import java.util.List; @Data @NoArgsConstructor @Entity @Table(name = "items") @JsonInclude(JsonInclude.Include.NON_NULL) @TypeDef(name = "json", typeClass = JsonType.class) public class Item { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Type(type = "json") @Column(columnDefinition = "vector") private List<Double> embedding; }
-
Create a JpaRepository interface that supports save and find. You can write custom findNearestNeighbors methods with native SQL
import org.springframework.data.jpa.repository.JpaRepository; public interface ItemRepository extends JpaRepository<Item, Long> { // Find nearest neighbors by a vector, for example value = "[1,2,3]" // This also works, cast is equals to the :: operator in postgresql //@Query(nativeQuery = true, value = "SELECT * FROM items ORDER BY embedding <-> cast(? as vector) LIMIT 5") @Query(nativeQuery = true, value = "SELECT * FROM items ORDER BY embedding <-> ? \\:\\:vector LIMIT 5") List<Item> findNearestNeighbors(String value); // Find nearest neighbors by a record in the same table @Query(nativeQuery = true, value = "SELECT * FROM items WHERE id != :id ORDER BY embedding <-> (SELECT embedding FROM items WHERE id = :id) LIMIT 5") List<Item> findNearestNeighbors(Long id); }
-
Test create, query and findNearestNeighbors:
@Autowired private ItemRepository itemRepository; @Test @Rollback(false) @Transactional public void createItem() { Item item = new Item(); Random rand = new Random(); List<Double> embedding = new ArrayList<>(); for (int i = 0; i < 3; i++) embedding.add(rand.nextDouble()); item.setEmbedding(embedding); itemRepository.save(item); } @Test public void loadItems() { final List<Item> items = itemRepository.findAll(); System.out.println(items); } @Test public void findNearestNeighbors() { final String value = "[0.1, 0.2, 0.3]"; final List<Item> items = itemRepository.findNearestNeighbors(value); System.out.println(items); }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论