132-Spring AI Alibaba Vector Neo4j 示例

本示例演示如何使用 Spring AI Alibaba 与 Neo4j 向量数据库集成,实现向量存储、检索和过滤功能。通过本示例,您将了解如何构建一个基于 Neo4j 的向量存储系统,并使用它来存储文档和执行相似性搜索。

1. 示例目标

我们将创建一个 Spring Boot 应用,实现以下功能:

  1. 文档向量存储 (/vector/neo4j/add):将文档转换为向量并存储到 Neo4j 数据库中。
  2. 相似性搜索 (/vector/neo4j/search):根据查询文本在 Neo4j 中搜索相似的文档。
  3. 过滤删除 (/vector/neo4j/delete-filter):使用过滤条件删除 Neo4j 中的文档。

2. 技术栈与核心依赖

  • Spring Boot 3.x
  • Spring AI Alibaba (用于对接阿里云 DashScope 通义大模型)
  • Spring AI Neo4j Vector Store (用于 Neo4j 向量存储)
  • Neo4j (图数据库,用于存储向量数据)
  • Maven (项目构建工具)

pom.xml 中,你需要引入以下核心依赖:

复制代码
<dependencies>
    <!-- Spring AI Alibaba 核心启动器,集成 DashScope -->
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
    </dependency>
    
    <!-- Spring Web 用于构建 RESTful API -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- Spring AI Vector Store 核心功能 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-vector-store</artifactId>
    </dependency>
    
    <!-- Spring AI Neo4j Vector Store 启动器 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-vector-store-neo4j</artifactId>
    </dependency>
</dependencies>

3. 项目配置

src/main/resources/application.yml 文件中,配置 DashScope API Key 和 Neo4j 连接信息。

复制代码
server:
  port: 8080

spring:
  application:
    name: vector-neo4j

  ai:
    dashscope:
      api-key: ${AI_DASHSCOPE_API_KEY} # 建议使用环境变量,更安全

    vectorstore:
      neo4j:
        initialize-schema: true
        database-name: neo4j
        index-name: yingzi_index
        embedding-dimension: 1536
        distance-type: cosine

  neo4j:
    uri: bolt://localhost:7687
    authentication:
      username: neo4j
      password: yingzi_password

重要提示

  • 请将 AI_DASHSCOPE_API_KEY 环境变量设置为你从阿里云获取的有效 API Key。
  • 确保 Neo4j 数据库已安装并运行在本地,默认端口为 7687。
  • 根据你的 Neo4j 配置,修改用户名和密码。

4. Neo4j 配置类

创建 Neo4jConfig.java 配置类,用于配置 Neo4j 驱动和向量存储:

复制代码
package com.alibaba.cloud.ai.example.vector.neo4j.config;

import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.embedding.TokenCountBatchingStrategy;
import org.springframework.ai.vectorstore.neo4j.Neo4jVectorStore;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Neo4jConfig {

    private static final Logger logger = LoggerFactory.getLogger(Neo4jConfig.class);

    @Value("${spring.neo4j.uri}")
    private String uri;
    @Value("${spring.neo4j.authentication.username}")
    private String username;
    @Value("${spring.neo4j.authentication.password}")
    private String password;

    @Value("${spring.ai.vectorstore.neo4j.database-name}")
    private String databaseName;
    @Value("${spring.ai.vectorstore.neo4j.distance-type}")
    private Neo4jVectorStore.Neo4jDistanceType distanceType;
    @Value("${spring.ai.vectorstore.neo4j.index-name}")
    private String indexName;
    @Value("${spring.ai.vectorstore.neo4j.initialize-schema}")
    private boolean initializeSchema;
    @Value("${spring.ai.vectorstore.neo4j.embedding-dimension}")
    private int embeddingDimension;

    @Bean
    public Driver driver() {
        return GraphDatabase.driver(uri,
                AuthTokens.basic(username, password));
    }

    @Bean(name = "neo4jVectorStore")
    public Neo4jVectorStore vectorStore(Driver driver, EmbeddingModel embeddingModel) {
        logger.info("create neo4j vector store");

        return Neo4jVectorStore.builder(driver, embeddingModel)
                .databaseName(databaseName)                // Optional: defaults to "neo4j"
                .distanceType(distanceType) // Optional: defaults to COSINE
                .embeddingDimension(embeddingDimension)    // Optional: defaults to 1536
                .label("Document")                     // Optional: defaults to "Document"
                .embeddingProperty("embedding")        // Optional: defaults to "embedding"
                .indexName(indexName)             // Optional: defaults to "spring-ai-document-index"
                .initializeSchema(initializeSchema)                // Optional: defaults to false
                .batchingStrategy(new TokenCountBatchingStrategy()) // Optional: defaults to TokenCountBatchingStrategy
                .build();
    }
}

5. 控制器实现

创建 Neo4jController.java 控制器类,实现向量存储和检索功能:

复制代码
package com.alibaba.cloud.ai.example.vector.neo4j.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.filter.Filter;
import org.springframework.ai.vectorstore.filter.FilterExpressionBuilder;
import org.springframework.ai.vectorstore.neo4j.Neo4jVectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/vector/neo4j")
public class Neo4jController {

    private static final Logger logger = LoggerFactory.getLogger(Neo4jController.class);
    private final Neo4jVectorStore neo4jVectorStore;

    @Autowired
    public Neo4jController(@Qualifier("neo4jVectorStore") Neo4jVectorStore neo4jVectorStore) {
        this.neo4jVectorStore = neo4jVectorStore;
    }

    @GetMapping("/add")
    public void add() {
        logger.info("start import data");

        HashMap<String, Object> map = new HashMap<>();
        map.put("id", "12345");
        map.put("year", 2025);
        map.put("name", "yingzi");
        List<Document> documents = List.of(
                new Document("The World is Big and Salvation Lurks Around the Corner"),
                new Document("You walk forward facing the past and you turn back toward the future.", Map.of("year", 2024)),
                new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", map));
        neo4jVectorStore.add(documents);
    }

    @GetMapping("/search")
    public List<Document> search() {
        logger.info("start search data");
        return neo4jVectorStore.similaritySearch(SearchRequest
                .builder()
                .query("Spring")
                .topK(2)
                .build());
    }

    @GetMapping("delete-filter")
    public void deleteFilter() {
        logger.info("start delete data with filter");
        FilterExpressionBuilder b = new FilterExpressionBuilder();
        Filter.Expression expression = b.and(
                b.in("year", 2025, 2024),
                b.eq("name", "yingzi")
        ).build();

        neo4jVectorStore.delete(expression);
    }
}

6. 主应用类

创建主应用类 VectorNeo4jApplication.java

复制代码
package com.alibaba.cloud.ai.example.vector.neo4j;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class VectorNeo4jApplication {

    public static void main(String[] args) {
        SpringApplication.run(VectorNeo4jApplication.class, args);
    }
}

7. 运行与测试

  1. 启动 Neo4j 数据库:确保 Neo4j 数据库已安装并运行。
  2. 设置环境变量 :设置 AI_DASHSCOPE_API_KEY 环境变量。
  3. 启动应用:运行 Spring Boot 主程序。
  4. 使用浏览器或 API 工具(如 Postman, curl)进行测试

测试 1:添加文档到向量存储

访问以下 URL,将示例文档添加到 Neo4j 向量存储中:

复制代码
http://localhost:8080/vector/neo4j/add

预期响应:无返回内容,但日志会显示 "start import data"。

测试 2:搜索相似文档

访问以下 URL,搜索与 "Spring" 相关的文档:

复制代码
http://localhost:8080/vector/neo4j/search

预期响应:返回与查询最相似的前 2 个文档的 JSON 数组:

复制代码
[
  {
    "content": "Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!",
    "metadata": {
      "id": "12345",
      "year": 2025,
      "name": "yingzi"
    },
    "id": "...",
    "score": 0.9...
  },
  {
    "content": "The World is Big and Salvation Lurks Around the Corner",
    "metadata": {},
    "id": "...",
    "score": 0.7...
  }
]

测试 3:使用过滤器删除文档

访问以下 URL,删除符合特定条件的文档:

复制代码
http://localhost:8080/vector/neo4j/delete-filter

预期响应:无返回内容,但日志会显示 "start delete data with filter"。

此操作将删除所有满足以下条件的文档:

  • 元数据中 "year" 字段为 2025 或 2024
  • 元数据中 "name" 字段为 "yingzi"

8. 实现思路与扩展建议

实现思路

本示例的核心是利用 Neo4j 作为向量数据库,实现文档的向量化存储和相似性检索。主要思路包括:

  • 向量化存储:将文本文档通过嵌入模型转换为向量,并存储在 Neo4j 中。
  • 相似性搜索:将查询文本转换为向量,在 Neo4j 中找到最相似的文档。
  • 元数据过滤:使用元数据属性对文档进行过滤和删除操作。

扩展建议

  • 批量导入:实现从文件系统或数据库批量导入文档到向量存储。
  • 高级过滤:支持更复杂的过滤条件,如范围查询、模糊匹配等。
  • 向量可视化:集成向量可视化工具,帮助理解向量空间中的文档分布。
  • 性能优化:针对大规模文档集,实现分批处理和异步操作。
  • 多模态支持:扩展支持图像、音频等多模态数据的向量化存储和检索。
  • 集成 RAG 系统:将向量检索与生成式 AI 结合,构建完整的检索增强生成系统。
相关推荐
mit6.8245 小时前
[nanoGPT] 性能与效率 | `torch.compile()` |`Flash Attention`|`混合精度训练`|`estimate_mfu`
人工智能
豆芽脚脚6 小时前
机器学习之数字识别
人工智能·机器学习
智海观潮6 小时前
Flink在与AI集成的路上再次“遥遥领先” - Flink Agents
大数据·人工智能·flink
honeysuckle_luo7 小时前
RandLA-net-pytorch 复现
人工智能·pytorch·python
_BugMan9 小时前
【大模型】理论基础(1):函数与神经网络
人工智能·深度学习·神经网络
AI模块工坊10 小时前
CVPR 即插即用 | PConv:重新定义高效卷积,一个让模型“跑”得更快、更省的新范式
人工智能·深度学习·计算机视觉·transformer
lzjava202410 小时前
Spring AI加DeepSeek实现一个Prompt聊天机器人
人工智能·spring·prompt
fanstuck12 小时前
AI辅助数学建模有哪些优势?
人工智能·数学建模·语言模型·aigc
一只安12 小时前
从零开发AI(不依赖任何模型)
人工智能·python