当前位置: 首页 > article >正文

Milvus 与 Spring Boot 集成

以下是将 Milvus 与 Spring Boot 集成的详细代码示例:

1. 添加依赖 (pom.xml)

<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Milvus Java SDK -->
    <dependency>
        <groupId>io.milvus</groupId>
        <artifactId>milvus-sdk-java</artifactId>
        <version>2.3.4</version> <!-- 使用最新版本 -->
    </dependency>

    <!-- Lombok 可选 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>
 

2. 配置参数 (application.yml)

milvus:
  host: localhost
  port: 19530
  collection-name: my_collection
  vector-dimension: 128

3. 配置类 (MilvusConfig.java)

import io.milvus.client.MilvusServiceClient;
import io.milvus.param.ConnectParam;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@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);
    }
}

4. 实体类 (ImageVector.java)

import lombok.Data;
import java.util.List;

@Data
public class ImageVector {
    private Long id;
    private List<Float> vector;
    private String imagePath;
}

5. 服务层 (MilvusService.java)

import io.milvus.client.MilvusServiceClient;
import io.milvus.param.*;
import io.milvus.param.collection.*;
import io.milvus.param.index.*;
import io.milvus.grpc.DataType;
import io.milvus.response.SearchResultsWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.*;

@Service
public class MilvusService {

    @Autowired
    private MilvusServiceClient milvusClient;

    @Value("${milvus.collection-name}")
    private String collectionName;

    @Value("${milvus.vector-dimension}")
    private Integer vectorDimension;

    // 创建集合
    public void createCollection() {
        FieldType idField = FieldType.newBuilder()
                .withName("id")
                .withDataType(DataType.Int64)
                .withPrimaryKey(true)
                .withAutoID(false)
                .build();

        FieldType vectorField = FieldType.newBuilder()
                .withName("vector")
                .withDataType(DataType.FloatVector)
                .withDimension(vectorDimension)
                .build();

        CreateCollectionParam createParam = CreateCollectionParam.newBuilder()
                .withCollectionName(collectionName)
                .withDescription("Image similarity search")
                .addFieldType(idField)
                .addFieldType(vectorField)
                .build();

        milvusClient.createCollection(createParam);
    }

    // 插入向量数据
    public void insertVectors(List<ImageVector> vectors) {
        List<Long> ids = new ArrayList<>();
        List<List<Float>> vectorsList = new ArrayList<>();

        for (ImageVector vector : vectors) {
            ids.add(vector.getId());
            vectorsList.add(vector.getVector());
        }

        InsertParam insertParam = InsertParam.newBuilder()
                .withCollectionName(collectionName)
                .withFields(
                        new HashMap<String, Object>() {{
                            put("id", ids);
                            put("vector", vectorsList);
                        }})
                .build();

        milvusClient.insert(insertParam);
    }

    // 向量相似度搜索
    public List<Long> searchSimilarVectors(List<Float> queryVector, int topK) {
        final String SEARCH_PARAM = "{\"nprobe\":10}";
        List<String> outputFields = Collections.singletonList("id");

        SearchParam searchParam = SearchParam.newBuilder()
                .withCollectionName(collectionName)
                .withVectorFieldName("vector")
                .withVectors(Collections.singletonList(queryVector))
                .withTopK(topK)
                .withParams(SEARCH_PARAM)
                .withOutFields(outputFields)
                .build();

        R<SearchResults> response = milvusClient.search(searchParam);
        SearchResultsWrapper wrapper = new SearchResultsWrapper(response.getData().getResults());

        return wrapper.getIDScore(0).getIds().stream()
                .map(id -> (Long) id)
                .toList();
    }
}

6. 控制器 (SearchController.java)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/api/search")
public class SearchController {

    @Autowired
    private MilvusService milvusService;

    @PostMapping("/similar")
    public List<Long> searchSimilar(@RequestBody List<Float> vector,
                                    @RequestParam(defaultValue = "10") int topK) {
        return milvusService.searchSimilarVectors(vector, topK);
    }

    @PostMapping("/upload")
    public String uploadImage(@RequestBody ImageVector imageVector) {
        milvusService.insertVectors(Collections.singletonList(imageVector));
        return "Vector uploaded successfully";
    }
}
 

7. 应用启动类 (Application.java)

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.PostConstruct;

@SpringBootApplication
public class Application {

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

    @PostConstruct
    public void init() {
        // 应用启动时创建集合(根据需求调整)
        // milvusService.createCollection();
    }
}
 

8. 使用示例

插入数据 (HTTP POST)
curl -X POST http://localhost:8080/api/search/upload \
-H "Content-Type: application/json" \
-d '{
    "id": 1,
    "vector": [0.12, 0.34, ..., 0.98], # 128维向量
    "imagePath": "/images/example.jpg"
}'
 
搜索相似 (HTTP POST)
curl -X POST http://localhost:8080/api/search/similar?topK=5 \
-H "Content-Type: application/json" \
-d '[0.15, 0.32, ..., 0.95]' # 查询向量
 

关键点说明:

  1. 索引优化:实际生产环境需要创建索引(如IVF_FLAT)

public void createIndex() {
    IndexType indexType = IndexType.IVF_FLAT;
    String indexParam = "{\"nlist\":1024}";

    CreateIndexParam createIndexParam = CreateIndexParam.newBuilder()
            .withCollectionName(collectionName)
            .withFieldName("vector")
            .withIndexType(indexType)
            .withExtraParam(indexParam)
            .build();

    milvusClient.createIndex(createIndexParam);
}
  1. 连接池配置:建议使用连接池管理客户端连接

@Bean
public MilvusServiceClient milvusClient() {
    ConnectParam connectParam = ConnectParam.newBuilder()
            .withHost(host)
            .withPort(port)
            .withConnectTimeout(30, TimeUnit.SECONDS) // 自定义超时时间
            .build();
    return new MilvusServiceClient(connectParam);
}
  1. 错误处理:建议添加全局异常处理

@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(MilvusException.class)
    public ResponseEntity<String> handleMilvusException(MilvusException e) {
        return ResponseEntity.status(500).body("Milvus Error: " + e.getMessage());
    }
}

该实现展示了:

  • Spring Boot 与 Milvus 的基本集成

  • 集合管理(创建/删除)

  • 数据插入和向量搜索

  • REST API 接口

  • 基础配置管理

实际生产环境中需要根据具体需求添加:

  • 认证机制

  • 更完善的错误处理

  • 性能优化(批量操作、异步处理)

  • 索引调优

  • 监控和日志记录


http://www.kler.cn/a/612327.html

相关文章:

  • SpringMVC 拦截器详解与实战
  • GAUSSDB 分布式存储机制深度解析
  • sortablejs el-table 树结构拖拽
  • PHP中yield关键字的使用
  • RestTemplate远程调用接口方式
  • 什么是视图,数据库的视图本质上就是个提前写好的sql语句,创建的一个虚拟表
  • C语言中把函数声明为inline是什么意思?
  • Nginx RTMP 处理模块 (ngx_rtmp_handler.c) 详细分析
  • Go语言分布式锁实战:dlock助力构建高并发稳定系统
  • 工作流引擎Flowable介绍及SpringBoot整合使用实例
  • ubuntu服务器server版安装,ssh远程连接xmanager管理,改ip网络连接。图文教程
  • 什么是 Promise?
  • 在鸿蒙 ArkUI 中使用本地数据缓存
  • 【数学建模】(启发式算法)蚁群算法(Ant Colony Optimization)的详解与应用
  • 深入理解椭圆曲线密码学(ECC)与区块链加密
  • 蓝桥杯模拟题--约数的个数(约数和质因数的区别)
  • spring-ai ollama小试牛刀
  • DaemonSet 与 Deployment 的主要区别
  • VSCode 抽风之 两个conda环境同时在被激活
  • 数字图像处理 -- 霍夫曼编码(无损压缩)练习