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]' # 查询向量
关键点说明:
-
索引优化:实际生产环境需要创建索引(如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);
}
-
连接池配置:建议使用连接池管理客户端连接
@Bean
public MilvusServiceClient milvusClient() {
ConnectParam connectParam = ConnectParam.newBuilder()
.withHost(host)
.withPort(port)
.withConnectTimeout(30, TimeUnit.SECONDS) // 自定义超时时间
.build();
return new MilvusServiceClient(connectParam);
}
-
错误处理:建议添加全局异常处理
@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 接口
-
基础配置管理
实际生产环境中需要根据具体需求添加:
-
认证机制
-
更完善的错误处理
-
性能优化(批量操作、异步处理)
-
索引调优
-
监控和日志记录