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 结合,构建完整的检索增强生成系统。
相关推荐
只是没名字11 分钟前
Codex CLI Windows 新手安装教程:从 Node.js 到首次运行
人工智能
用户86306526961313 分钟前
Krea 2 LoRA 训练全流程踩坑记录:从打标到双卡并行的 Windows 原生实战
人工智能
木雷坞2 小时前
让 AI 编程助手跑得起项目:Dev Container 实践记录
人工智能
腾讯云开发者3 小时前
港科大郭毅可谈Agentic AI时代的核心命题:人机共生,人不可能退场
人工智能
常丛丛3 小时前
5.6 LangGraph-Edges理解-Agent图的道路系统
人工智能
雪隐3 小时前
个人电脑玩AI-08让5060 Ti给你打工——我拿 Unlimited-OCR扫了 600 页书,然后悟了
人工智能·后端
Coffeeee3 小时前
Prompt要花心思写,与 AI 对话的七个技巧
人工智能·aigc·ai编程
蝎子莱莱爱打怪4 小时前
Claude Code 官宣新升级:子智能体默认后台跑,你边聊它边干活
人工智能
武子康4 小时前
调查研究-206 DeepSeek DSpark 深度解析:大模型推理加速,正在从“模型能力”转向“系统工程”
人工智能·agent·deepseek