1.概述

本文介绍一下如何使用 postgres 作为向量数据库,首先我们需要安装 postgres 数据库,接下来安装 pgvector 扩展支持,关于安装之前有介绍,这里就不再介绍

2.实现步骤

2.1 增加依赖

<dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-vector-store-pgvector</artifactId>
        </dependency>

2.2 增加配置

spring:
	ai:
		vectorstore:
			pgvector:
				index-type: HNSW
				distance-type: COSINE_DISTANCE
				# 维度指定,需要看 向量模型的配置
				dimensions: 1024
				max-document-batch-size: 10000
				initialize-schema: true
	datasource:
		url: jdbc:postgresql://192.168.2.14:5432/postgres
		username: postgres
		password: postgres

2.3 启动应用

做好前面两步后,我们可以启动应用,启动应用后,由于我们用的是 initialize-schema: true,所以应用启动后,系统会自动帮我创建好向量数据库的表。

image

2.4 向量入库测试

编写代码插入向量数据库表

	@Autowired
    public  VectorStore vectorStore;


    @GetMapping("/addDoc")
    public ResponseEntity <String> addDoc(){

        List<Document> documents = List.of(
                // 1. 刘备
                new Document("10001",
                        "刘备,字玄德,蜀汉昭烈皇帝。中山靖王刘胜之后,三国时期蜀汉开国皇帝。以仁德著称,三顾茅庐请诸葛亮出山,建立蜀汉政权。",
                        new HashMap<String, Object>() {{
                            put("name", "刘备");
                            put("prop", "仁德治国,三顾茅庐");
                        }}),

                // 2. 诸葛亮
                new Document("10002",
                        "诸葛亮,字孔明,号卧龙,蜀汉丞相。被誉为'智圣',精通兵法、天文、地理。著有《出师表》《诫子书》等,发明木牛流马、孔明灯等。",
                        new HashMap<String, Object>() {{
                            put("name", "诸葛亮");
                            put("prop", "运筹帷幄,发明创造");
                        }}),

                // 3. 曹操
                new Document("10003",
                        "曹操,字孟德,魏武帝。东汉末年杰出政治家、军事家、文学家。统一北方,实行屯田制,著有《观沧海》《短歌行》等诗篇。",
                        new HashMap<String, Object>() {{
                            put("name", "曹操");
                            put("prop", "统一北方,诗词文学");
                        }}),

                // 4. 孙权
                new Document("10004",
                        "孙权,字仲谋,吴大帝。三国时期东吴开国皇帝,继承父兄基业,联合刘备赤壁破曹,善于用人,开发江南。",
                        new HashMap<String, Object>() {{
                            put("name", "孙权");
                            put("prop", "知人善任,开发江南");
                        }}),

                // 5. 张飞
                new Document("10005",
                        "张飞,字翼德,蜀汉车骑将军。勇猛过人,据水断桥喝退曹军,义释严颜,与关羽并称'万人敌'。",
                        new HashMap<String, Object>() {{
                            put("name", "张飞");
                            put("prop", "勇猛过人,万人敌");
                        }}),

                // 6. 吕布
                new Document("10006",
                        "吕布,字奉先,三国第一猛将。手持方天画戟,骑赤兔马,有'人中吕布,马中赤兔'之称。先后认丁原、董卓为义父,后被曹操所杀。",
                        new HashMap<String, Object>() {{
                            put("name", "吕布");
                            put("prop", "武艺第一,三姓家奴");
                        }}),

                // 7. 赵云
                new Document("10007",
                        "赵云,字子龙,蜀汉翊军将军。常山赵子龙,单骑救主,截江夺阿斗,汉水空城计,被刘备称为'一身都是胆'。",
                        new HashMap<String, Object>() {{
                            put("name", "赵云");
                            put("prop", "单骑救主,一身是胆");
                        }}),

                // 8. 司马懿
                new Document("10008",
                        "司马懿,字仲达,晋宣帝。魏国杰出政治家、军事家,多次抵御诸葛亮北伐,最终发动高平陵之变,为西晋奠基人。",
                        new HashMap<String, Object>() {{
                            put("name", "司马懿");
                            put("prop", "老谋深算,篡魏建晋");
                        }}),

                // 9. 周瑜
                new Document("10009",
                        "周瑜,字公瑾,东吴大都督。美姿容,精音律,有'美周郎'之称。赤壁之战中火烧曹操水军,奠定三分天下格局。",
                        new HashMap<String, Object>() {{
                            put("name", "周瑜");
                            put("prop", "精通音律,赤壁破曹");
                        }}),

                // 10. 黄忠
                new Document("10010",
                        "黄忠,字汉升,蜀汉后将军。本为刘表部将,后归刘备。定军山斩夏侯渊,勇冠三军,与关羽、张飞、马超、赵云并称五虎上将。",
                        new HashMap<String, Object>() {{
                            put("name", "黄忠");
                            put("prop", "老当益壮,定军斩将");
                        }})
        );

        vectorStore.add(documents);

        return ResponseEntity.ok("Added Documents");
    }

添加完成后,我们可以查看pg数据库
image

2.5 查询数据

@GetMapping("/search")
    public ResponseEntity <List<Document>> search(@RequestParam("query")String query){
        Filter.Expression filterExpression = new Filter.Expression(Filter.ExpressionType.OR,
                new Filter.Expression(Filter.ExpressionType.EQ, new Filter.Key("name"),new Filter.Value("刘备")),
                new Filter.Expression(Filter.ExpressionType.EQ, new Filter.Key("name"),new Filter.Value("张飞")));
        List<Document> results = this.vectorStore.
                similaritySearch(SearchRequest.builder()
                        .filterExpression(filterExpression)
                        .query(query).topK(2).build());
        return ResponseEntity.ok(results);
    }

查询数据数据时,我们可以按照 元数据 和 向量查询。

2.6 创建索引

我们如果需要基于metadata 查询,需要创建索引,加快查询

  • 不要自动创建数据库表
    vectorstore:
      pgvector:
	    # 指定生成的表名
        table-name: article
        index-type: HNSW
        distance-type: COSINE_DISTANCE
        dimensions: 1024
        max-document-batch-size: 10000
        initialize-schema: false
        id-type: serial
  • 创建数据库表
CREATE TABLE article (
    id bigserial PRIMARY KEY,
    content text,
	# 注意这里时JSONB
    metadata jsonb, 
	# 向量维度需要根据嵌入模型来
    embedding vector(1024)
);

在字段上创建索引

CREATE INDEX idx_vector_store_metadata ON article USING GIN (metadata);
# 在某个属性上创建索引
CREATE INDEX idx_vector_store_name ON article USING GIN ((metadata->'name'));
posted on 2025-09-01 16:02  自由港  阅读(50)  评论(0)    收藏  举报