Spring Boot 集成 Milvus 向量数据库(DeepSeek RAG)

2,463 阅读2分钟

一、前置准备

  1. 安装 Milvus

    • 单机版:docker-compose up -d(使用官方 Docker 配置
    • 集群版:参考官方部署文档
  2. Milvus Java SDK

    xmlCopy Code
    <dependency>
        <groupId>io.milvus</groupId>
        <artifactId>milvus-sdk-java</artifactId>
        <version>2.3.4</version> <!-- 根据版本更新 -->
    </dependency>
    

二、SpringBoot 集成步骤

1. 配置连接参数(application.yml

yamlCopy Code
milvus:
  host: 127.0.0.1
  port: 19530
  collection-name: product_vectors # 自定义集合名称
  vector-dim: 512                 # 向量维度(需与实际数据匹配)

2. 配置 Milvus 客户端 Bean

javaCopy Code
@Configuration
public class MilvusConfig {
    @Value("${milvus.host}")
    private String host;
    @Value("${milvus.port}")
    private int port;

    @Bean
    public MilvusServiceClient milvusClient() {
        ConnectParam connectParam = ConnectParam.newBuilder()
                .withHost(host)
                .withPort(port)
                .build();
        return new MilvusServiceClient(connectParam);
    }
}

3. 定义向量操作服务类

javaCopy Code
@Service
public class VectorSearchService {
    @Autowired
    private MilvusServiceClient milvusClient;
    @Value("${milvus.collection-name}")
    private String collectionName;
    @Value("${milvus.vector-dim}")
    private Integer vectorDim;

    // 创建集合(首次使用)
    public void createCollection() {
        FieldType fieldId = FieldType.newBuilder()
                .withName("id")
                .withDataType(DataType.Int64)
                .withPrimaryKey(true)
                .build();
        FieldType fieldVector = FieldType.newBuilder()
                .withName("vector")
                .withDataType(DataType.FloatVector)
                .withDimension(vectorDim)
                .build();
        CreateCollectionParam createParam = CreateCollectionParam.newBuilder()
                .withCollectionName(collectionName)
                .addFieldType(fieldId)
                .addFieldType(fieldVector)
                .build();
        milvusClient.createCollection(createParam);
    }

    // 插入向量数据
    public List<Long> insertVectors(List<List<Float>> vectors) {
        List<Long> ids = generateIds(vectors.size()); // 生成唯一ID(如雪花算法)
        InsertParam insertParam = InsertParam.newBuilder()
                .withCollectionName(collectionName)
                .addField("id", ids)
                .addField("vector", vectors)
                .build();
        milvusClient.insert(insertParam);
        return ids;
    }

    // 向量相似度搜索(Top-K)
    public List<Long> searchSimilarVectors(List<Float> queryVector, int topK) {
        List<List<Float>> queryVectors = Collections.singletonList(queryVector);
        SearchParam searchParam = SearchParam.newBuilder()
                .withCollectionName(collectionName)
                .withVectors(queryVectors)
                .withTopK(topK)
                .withMetricType(MetricType.L2) // 或 COSINE/IP
                .build();
        SearchResults resp = milvusClient.search(searchParam);
        return parseResultIds(resp);
    }
}

三、实际用例:商品图片相似推荐

场景描述

  • 用户上传一张商品图片 → 提取图片特征向量(如 ResNet-512D) → 在 Milvus 中搜索 Top-5 相似商品

控制器层代码

javaCopy Code
@RestController
@RequestMapping("/api/search")
public class SearchController {
    @Autowired
    private VectorSearchService vectorService;

    @PostMapping("/image")
    public ResponseEntity<?> searchByImage(@RequestBody float[] imageFeatures) {
        // 转换为List<Float>(Milvus要求格式)
        List<Float> queryVector = Arrays.stream(imageFeatures).boxed().collect(Collectors.toList());
        List<Long> productIds = vectorService.searchSimilarVectors(queryVector, 5);
        return ResponseEntity.ok(productIds);
    }
}

四、关键注意事项

  1. 性能优化

    • 插入数据后调用 flush() 确保数据持久化

    • 创建索引(如 IVF_FLAT 或 HNSW)加速搜索:

      javaCopy Code
      milvusClient.createIndex(CreateIndexParam.newBuilder()
          .withCollectionName(collectionName)
          .withFieldName("vector")
          .withIndexType(IndexType.IVF_FLAT)
          .withMetricType(MetricType.L2)
          .build());
      
  2. 错误处理

    • 检查响应状态码:resp.getStatus() == Status.Success.code
    • 处理 MilvusException 异常
  3. 版本兼容性

    • Milvus 2.x 与 1.x API 不兼容,需确认 SDK 版本