Milvus向量解析 + Spring Boot3 整合完整实战案例(入门到精通)

你想先理解Milvus向量的核心概念,再获取一个与Spring Boot3整合的、覆盖实战场景的完整项目案例,我会从概念拆解到代码落地,再到进阶优化,带你吃透Milvus在Spring Boot中的应用。

一、核心概念:什么是Milvus向量?

1. 先搞懂「向量」(Embedding)

  • 本质:向量是将文本、图片、音频等非结构化数据,通过AI模型(Embedding模型)转换成的一组数字数组(如 [0.12, 0.34, -0.56, ...]),数组长度就是「向量维度」(如豆包Embedding是1536维)。
  • 核心作用:把「语义/特征相似」的内容,转换成「数值距离相近」的向量(比如“苹果手机”和“iPhone”的向量距离很近,“苹果手机”和“香蕉”的向量距离很远)。

2. Milvus向量数据库

Milvus是专为向量数据设计的开源数据库,核心能力是:

  • 存储海量向量数据(亿级/百亿级);
  • 快速检索与目标向量「语义/特征相似」的向量(毫秒级响应);
  • 支持多种相似度算法(余弦相似度、欧氏距离等)和索引类型(平衡精度与性能)。

3. 核心价值

解决传统关系型数据库「模糊查询(LIKE %关键词%)」的两大痛点:

维度 关系型数据库模糊查询 Milvus向量检索
检索逻辑 字符匹配,无语义理解 语义匹配,理解内容相似性
大数据量性能 百万级数据秒级/分钟级响应 亿级数据毫秒级响应
检索精度 依赖关键词,易漏查/误查 语义相似即能命中,精度更高

二、实战项目:Spring Boot3 + Milvus 智能知识库

项目背景

实现一个「智能问答知识库」:用户提问后,系统先从海量知识库中语义检索相似内容,再结合LLM(豆包)生成精准回答,覆盖「数据入库→向量检索→RAG问答→性能优化」全流程。

环境准备

组件 版本/要求 部署方式
JDK 17+(Spring Boot3 要求) 本地
Spring Boot 3.2.0+ 本地
Milvus 2.4.3(单机版,入门首选) Docker(一键部署)
MySQL 8.0+(存储原始文本数据) 本地/Docker
豆包API Key 可调用LLM和Embedding接口 官网申请(https://www.doubao.com/open/)
Milvus Docker部署(Windows/Linux/Mac通用)
# 1. 创建目录并下载配置文件
mkdir -p ~/milvus && cd ~/milvus
wget https://github.com/milvus-io/milvus/releases/download/v2.4.3/milvus-standalone-docker-compose.yml -O docker-compose.yml

# 2. 启动Milvus(需提前安装Docker & Docker Compose)
docker-compose up -d

# 3. 验证启动成功(看到 milvus-standalone 状态为 Up 即可)
docker-compose ps

# 4. 常用命令
# 停止Milvus
docker-compose down
# 查看日志
docker-compose logs -f milvus-standalone

阶段1:项目基础搭建(入门)

1.1 新建Spring Boot项目,配置pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>milvus-springboot-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>milvus-springboot-demo</name>
    <description>Spring Boot3 + Milvus 智能知识库</description>

    <properties>
        <java.version>17</java.version>
        <milvus-sdk.version>2.4.3</milvus-sdk.version>
        <langchain4j.version>0.32.0</langchain4j.version>
        <mybatis-plus.version>3.5.5</mybatis-plus.version>
    </properties>

    <dependencies>
        <!-- Spring Boot核心 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <!-- Milvus -->
        <dependency>
            <groupId>io.milvus</groupId>
            <artifactId>milvus-sdk-java</artifactId>
            <version>${milvus-sdk.version}</version>
        </dependency>
        <!-- LangChain4j整合Milvus(简化向量操作) -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-milvus</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>

        <!-- Embedding/LLM(豆包) -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>

        <!-- MyBatis-Plus(存储原始文本) -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>

        <!-- MySQL驱动 -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- 工具类 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </dependency>

        <!-- 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
1.2 配置文件(application.yml)
server:
  port: 8080 # 服务端口

spring:
  # 数据库配置(存储原始知识库文本)
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/milvus_demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root # 替换为你的MySQL用户名
    password: 123456 # 替换为你的MySQL密码
  # 日志配置
  logging:
    level:
      com.example: debug
      io.milvus: info

# MyBatis-Plus配置
mybatis-plus:
  mapper-locations: classpath:mapper/**/*.xml
  type-aliases-package: com.example.entity
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

# Milvus配置
milvus:
  host: 127.0.0.1
  port: 19530
  database-name: default
  collection-name: knowledge_vector # 向量集合(相当于表)
  dimension: 1536 # 豆包Embedding维度
  index-type: IVF_FLAT # 入门索引类型
  metric-type: COSINE # 余弦相似度

# 豆包配置(LLM + Embedding)
doubao:
  api-key: your-doubao-api-key # 替换为你的API Key
  base-url: https://api.doubao.com/openai/v1
  llm-model: doubao-pro
  embedding-model: doubao-embedding
  temperature: 0.7
  max-tokens: 2000

# Prompt模板配置
prompt:
  rag-template: |
    请严格按照以下规则回答用户问题:
    1. 仅使用参考知识中的内容,禁止编造任何信息;
    2. 回答简洁明了,逻辑清晰,不超过500字;
    3. 如果参考知识无相关内容,直接回答"暂无相关知识"。
    
    参考知识:
    {related_knowledge}
    
    用户问题:{question}
1.3 初始化数据库

创建数据库 milvus_demo,执行以下SQL:

-- 知识库表(存储原始文本)
CREATE TABLE `knowledge_base` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `title` varchar(255) NOT NULL COMMENT '知识标题',
  `content` text NOT NULL COMMENT '知识内容',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='智能知识库表';

-- 插入测试数据(可批量插入1000+条模拟大数据量)
INSERT INTO `knowledge_base` (`title`, `content`) VALUES
('Spring Boot3核心特性', 'Spring Boot3基于Spring Framework 6构建,最低要求JDK17版本。核心特性包括:原生镜像支持、AOT编译、简化的配置注解、内置HTTP/2支持、与GraalVM兼容等,大幅提升启动速度和运行效率。'),
('MyBatis-Plus常用操作', 'MyBatis-Plus的CRUD操作无需编写XML,通过BaseMapper即可实现。常用方法:selectById(根据ID查询)、insert(新增)、updateById(更新)、deleteById(删除)、page(分页查询)。还支持条件构造器Wrapper,灵活拼接查询条件。'),
('Milvus向量检索原理', 'Milvus通过向量索引加速检索,IVF_FLAT索引将向量分桶,检索时先找相似桶再比较;余弦相似度用于计算向量间的相似程度,值越接近1表示语义越相似。'),
('LangChain4j RAG流程', 'LangChain4j实现RAG的核心步骤:1.将知识库文本转为向量存入向量库;2.用户问题转为向量;3.检索相似向量对应的文本;4.结合文本生成回答。');

阶段2:核心代码实现(入门→进阶)

2.1 实体类
2.1.1 知识库实体(KnowledgeBase.java)
package com.example.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.time.LocalDateTime;

@Data
@TableName("knowledge_base")
public class KnowledgeBase {
    /** 主键ID */
    @TableId(type = IdType.AUTO)
    private Long id;
    /** 知识标题 */
    private String title;
    /** 知识内容 */
    private String content;
    /** 创建时间 */
    private LocalDateTime createTime;
    /** 更新时间 */
    private LocalDateTime updateTime;
}
2.1.2 配置属性类(绑定yml配置)
package com.example.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 */
@Data
@Component
@ConfigurationProperties(prefix = "milvus")
public class MilvusProperties {
    private String host;
    private Integer port;
    private String databaseName;
    private String collectionName;
    private Integer dimension;
    private String indexType;
    private String metricType;
}

// 豆包配置属性类
@Data
@Component
@ConfigurationProperties(prefix = "doubao")
class DouBaoProperties {
    private String apiKey;
    private String baseUrl;
    private String llmModel;
    private String embeddingModel;
    private Double temperature;
    private Integer maxTokens;
}

// Prompt配置属性类
@Data
@Component
@ConfigurationProperties(prefix = "prompt")
class PromptProperties {
    private String ragTemplate;
}
2.2 核心配置类(Milvus + Embedding + LLM)
package com.example.config;

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
import dev.langchain4j.store.embedding.milvus.MilvusEmbeddingStore;
import io.milvus.param.ConnectParam;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.time.Duration;

/**
 * 核心组件配置:Milvus向量存储、Embedding模型、LLM模型
 */
@Configuration
public class CoreConfig {

    @Resource
    private MilvusProperties milvusProperties;

    @Resource
    private DouBaoProperties douBaoProperties;

    /**
     * 1. 初始化豆包Embedding模型(文本→向量)
     */
    @Bean
    public EmbeddingModel doubaoEmbeddingModel() {
        return OpenAiEmbeddingModel.builder()
                .apiKey(douBaoProperties.getApiKey())
                .baseUrl(douBaoProperties.getBaseUrl() + "/embeddings")
                .modelName(douBaoProperties.getEmbeddingModel())
                .timeout(Duration.ofMinutes(1))
                .build();
    }

    /**
     * 2. 初始化Milvus向量存储
     */
    @Bean
    public MilvusEmbeddingStore milvusEmbeddingStore() {
        // Milvus连接参数
        ConnectParam connectParam = ConnectParam.newBuilder()
                .withHost(milvusProperties.getHost())
                .withPort(milvusProperties.getPort())
                .withDatabaseName(milvusProperties.getDatabaseName())
                .build();

        // 构建向量存储(LangChain4j封装,简化操作)
        return MilvusEmbeddingStore.builder()
                .connectParam(connectParam)
                .collectionName(milvusProperties.getCollectionName())
                .dimension(milvusProperties.getDimension()) // 必须与Embedding维度一致
                .indexType(milvusProperties.getIndexType())
                .metricType(milvusProperties.getMetricType())
                .build();
    }

    /**
     * 3. 初始化豆包LLM模型(生成回答)
     */
    @Bean
    public ChatLanguageModel doubaoChatModel() {
        return OpenAiChatModel.builder()
                .apiKey(douBaoProperties.getApiKey())
                .baseUrl(douBaoProperties.getBaseUrl())
                .modelName(douBaoProperties.getLlmModel())
                .temperature(douBaoProperties.getTemperature())
                .maxTokens(douBaoProperties.getMaxTokens())
                .timeout(Duration.ofMinutes(1))
                .build();
    }
}
2.3 数据访问层(MyBatis-Plus)
2.3.1 Mapper接口(KnowledgeBaseMapper.java)
package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.KnowledgeBase;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface KnowledgeBaseMapper extends BaseMapper<KnowledgeBase> {
}
2.3.2 Service层(知识库CRUD)
package com.example.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.KnowledgeBase;
import com.example.mapper.KnowledgeBaseMapper;
import org.springframework.stereotype.Service;

@Service
public class KnowledgeBaseService extends ServiceImpl<KnowledgeBaseMapper, KnowledgeBase> {
    // 复用MyBatis-Plus的CRUD方法,无需额外编写
}
2.4 核心业务层(向量入库 + 语义检索 + RAG问答)
2.4.1 向量入库服务(VectorIngestService.java)
package com.example.service;

import com.example.entity.KnowledgeBase;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.Metadata;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.milvus.MilvusEmbeddingStore;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 向量入库服务:将知识库文本转为向量存入Milvus
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VectorIngestService {

    private final KnowledgeBaseService knowledgeBaseService;
    private final EmbeddingModel doubaoEmbeddingModel;
    private final MilvusEmbeddingStore milvusEmbeddingStore;

    /**
     * 全量入库:将MySQL中的所有知识库数据转为向量存入Milvus
     */
    @Transactional(rollbackFor = Exception.class)
    public void fullIngest() {
        // 1. 从MySQL读取所有知识库数据
        List<KnowledgeBase> knowledgeList = knowledgeBaseService.list();
        if (knowledgeList.isEmpty()) {
            log.warn("知识库无数据,跳过向量入库");
            return;
        }

        // 2. 初始化向量入库器(自动分片、转向量、入库)
        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                .embeddingModel(doubaoEmbeddingModel)
                .embeddingStore(milvusEmbeddingStore)
                .build();

        // 3. 批量入库(性能优于逐行入库)
        List<Document> documents = knowledgeList.stream()
                .map(knowledge -> Document.from(
                        knowledge.getContent(),
                        Metadata.from("id", knowledge.getId().toString(), "title", knowledge.getTitle())
                ))
                .toList();
        ingestor.ingest(documents);

        log.info("向量全量入库完成,共处理{}条数据", knowledgeList.size());
    }

    /**
     * 增量入库:新增单条知识库数据时同步向量
     */
    @Transactional(rollbackFor = Exception.class)
    public void incrementalIngest(KnowledgeBase knowledge) {
        // 1. 先保存到MySQL
        knowledgeBaseService.save(knowledge);

        // 2. 转为向量存入Milvus
        Document document = Document.from(
                knowledge.getContent(),
                Metadata.from("id", knowledge.getId().toString(), "title", knowledge.getTitle())
        );
        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                .embeddingModel(doubaoEmbeddingModel)
                .embeddingStore(milvusEmbeddingStore)
                .build();
        ingestor.ingest(document);

        log.info("增量入库完成,知识库ID:{}", knowledge.getId());
    }
}
2.4.2 语义检索服务(VectorSearchService.java)
package com.example.service;

import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.milvus.MilvusEmbeddingStore;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 向量检索服务:语义检索相似知识
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VectorSearchService {

    private final EmbeddingModel doubaoEmbeddingModel;
    private final MilvusEmbeddingStore milvusEmbeddingStore;

    /**
     * 语义检索
     * @param query 用户问题
     * @param topK 返回最相似的K条结果
     * @param similarityThreshold 相似度阈值(过滤低相似结果)
     * @return 相似知识文本列表
     */
    public List<String> semanticSearch(String query, int topK, double similarityThreshold) {
        try {
            // 1. 将用户问题转为向量
            Embedding queryEmbedding = doubaoEmbeddingModel.embed(query).content();

            // 2. Milvus检索相似向量
            List<EmbeddingMatch<TextSegment>> matches = milvusEmbeddingStore.findRelevant(queryEmbedding, topK);

            // 3. 过滤低相似度结果,提取文本
            return matches.stream()
                    .filter(match -> match.score() >= similarityThreshold)
                    .peek(match -> log.debug("检索到相似内容,相似度:{}", match.score()))
                    .map(match -> match.embedded().text())
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("语义检索失败", e);
            return List.of();
        }
    }
}
2.4.3 RAG问答服务(RagService.java)
package com.example.service;

import cn.hutool.core.collection.CollectionUtil;
import com.example.config.PromptProperties;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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

/**
 * RAG问答服务:向量检索 + LLM生成回答
 */
@Service
@RequiredArgsConstructor
public class RagService {

    private final VectorSearchService vectorSearchService;
    private final ChatLanguageModel doubaoChatModel;
    private final PromptProperties promptProperties;

    /**
     * 智能问答
     */
    public String smartAnswer(String question) {
        // 1. 语义检索相似知识(取Top5,相似度阈值0.7)
        List<String> relatedKnowledge = vectorSearchService.semanticSearch(question, 5, 0.7);

        // 2. 构建Prompt
        String knowledgeStr = CollectionUtil.isEmpty(relatedKnowledge)
                ? "无相关参考知识,请直接回答问题"
                : String.join("\n", relatedKnowledge);

        PromptTemplate promptTemplate = PromptTemplate.from(promptProperties.getRagTemplate());
        Map<String, Object> params = new HashMap<>();
        params.put("related_knowledge", knowledgeStr);
        params.put("question", question);
        Prompt prompt = promptTemplate.apply(params);

        // 3. 调用LLM生成回答
        return doubaoChatModel.generate(prompt.text());
    }
}
2.5 控制器层(接口暴露)
package com.example.controller;

import com.example.entity.KnowledgeBase;
import com.example.service.RagService;
import com.example.service.VectorIngestService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

/**
 * 智能知识库控制器
 */
@RestController
@RequestMapping("/api/knowledge")
@RequiredArgsConstructor
public class KnowledgeController {

    private final VectorIngestService vectorIngestService;
    private final RagService ragService;

    /**
     * 1. 全量向量入库(初始化时调用)
     */
    @PostMapping("/ingest/full")
    public String fullIngest() {
        vectorIngestService.fullIngest();
        return "全量入库成功";
    }

    /**
     * 2. 增量入库(新增知识库)
     */
    @PostMapping("/ingest/incremental")
    public String incrementalIngest(@RequestBody KnowledgeBase knowledge) {
        vectorIngestService.incrementalIngest(knowledge);
        return "增量入库成功,知识库ID:" + knowledge.getId();
    }

    /**
     * 3. 智能问答(核心接口)
     */
    @GetMapping("/answer")
    public String smartAnswer(@RequestParam String question) {
        return ragService.smartAnswer(question);
    }
}
2.6 启动类
package com.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@SpringBootApplication
@MapperScan("com.example.mapper") // 扫描Mapper接口
@EnableConfigurationProperties // 启用自定义配置属性
public class MilvusSpringbootDemoApplication {

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

阶段3:测试验证(入门)

3.1 全量向量入库

启动项目后,调用接口触发全量入库:

# POST请求
curl -X POST http://localhost:8080/api/knowledge/ingest/full

预期结果:控制台打印“向量全量入库完成,共处理X条数据”,Milvus中生成knowledge_vector集合并存储向量。

3.2 增量入库

新增一条知识库数据:

# POST请求(JSON格式)
curl -X POST -H "Content-Type: application/json" -d '{
    "title": "Milvus索引类型",
    "content": "Milvus常用索引类型:IVF_FLAT(入门首选,平衡精度和性能)、HNSW(检索速度快,适合高并发)、DISKANN(超大数据集)。IVF_FLAT的nlist参数建议设置为数据量的平方根。"
}' http://localhost:8080/api/knowledge/ingest/incremental

预期结果:返回“增量入库成功,知识库ID:X”,数据同时存入MySQL和Milvus。

3.3 智能问答(核心场景)

调用问答接口,测试语义检索效果:

# GET请求
curl http://localhost:8080/api/knowledge/answer?question=Milvus的IVF_FLAT索引怎么配置

预期结果

Milvus的IVF_FLAT索引是入门首选,平衡精度和性能。IVF_FLAT的nlist参数建议设置为数据量的平方根。

(即使问题表述与数据库中“Milvus常用索引类型…”的文本不完全一致,也能精准检索到相关内容)

阶段4:进阶优化(精通)

4.1 性能优化(大数据量)
4.1.1 Milvus索引调优
  • 百万级数据:将索引类型从IVF_FLAT改为HNSW,配置参数:
    milvus:
      index-type: HNSW
      # HNSW参数(可根据需求调整)
      hnsw-m: 16
      hnsw-ef-construction: 200
      hnsw-ef-search: 100
    
  • 调整nlist(IVF_FLAT):nlist = 根号(数据量)(如10万数据设为300)。
4.1.2 批量检索与缓存
// 在VectorSearchService中增加缓存(引入Spring Cache)
@Cacheable(value = "vectorSearchCache", key = "#query + '_' + #topK", expire = 3600)
public List<String> semanticSearch(String query, int topK, double similarityThreshold) {
    // 原有检索逻辑
}
4.2 数据管理(生产级)
4.2.1 向量删除
// 在VectorIngestService中新增删除方法
public void deleteKnowledge(Long knowledgeId) {
    // 1. 删除MySQL数据
    knowledgeBaseService.removeById(knowledgeId);
    // 2. 删除Milvus向量(根据元数据ID)
    milvusEmbeddingStore.deleteByMetadata("id", knowledgeId.toString());
    log.info("删除知识库ID:{},同步删除向量", knowledgeId);
}
4.2.2 向量更新
// 在VectorIngestService中新增更新方法
public void updateKnowledge(KnowledgeBase knowledge) {
    // 1. 删除旧向量
    milvusEmbeddingStore.deleteByMetadata("id", knowledge.getId().toString());
    // 2. 更新MySQL数据
    knowledgeBaseService.updateById(knowledge);
    // 3. 插入新向量
    incrementalIngest(knowledge);
    log.info("更新知识库ID:{},同步更新向量", knowledge.getId());
}
4.3 分布式部署(超大数据量)
  • Milvus从Standalone升级为Cluster模式(支持分片、副本);
  • 引入消息队列(如RocketMQ)异步处理向量入库,避免接口阻塞;
  • 使用分布式缓存(Redis Cluster)缓存检索结果。
4.4 监控告警
  • 集成Spring Boot Actuator监控Milvus连接状态、检索耗时;
  • 监控Embedding API调用成功率、LLM响应时间;
  • 配置告警:检索耗时>500ms、向量入库失败等。

阶段5:实战应用场景(精通)

场景1:企业内部智能问答
  • 落地方式:将企业文档、产品手册、FAQ转为向量存入Milvus,员工提问后快速检索并生成回答;
  • 核心价值:替代传统关键词搜索,提升知识获取效率。
场景2:电商智能客服
  • 落地方式:将商品信息、售后政策、常见问题转为向量,用户咨询时语义检索相关内容,生成精准回复;
  • 核心价值:降低人工客服成本,提升回复准确率。
场景3:智能文档分析
  • 落地方式:上传PDF/Word文档,解析文本后转为向量,支持“以问找文”(如“文档中关于Spring Boot3的内容有哪些”);
  • 核心价值:替代人工翻阅文档,提升分析效率。

三、总结

核心要点回顾

  1. Milvus向量核心:向量是文本的数值化表示,Milvus专注于向量的高效存储与语义检索,解决传统数据库“语义理解差、大数据量性能低”的问题;
  2. Spring Boot3整合核心:通过Milvus Java SDK/LangChain4j实现向量操作,Embedding模型转文本为向量,LLM模型生成回答,MyBatis-Plus存储原始文本;
  3. 实战关键:入门先实现“向量入库→语义检索→RAG问答”基础流程,进阶重点做性能优化(索引、缓存)、数据管理(增删改)、分布式部署,适配生产场景。

落地建议

  • 小数据量(万级):使用Milvus Standalone + 本地缓存,快速落地;
  • 中数据量(百万级):Milvus Cluster + 异步入库 + Redis缓存;
  • 大数据量(亿级):Milvus Cluster + 分片 + 分布式缓存 + 消息队列。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐