掘金 人工智能 06月04日 16:18
SpringBoot集成Milvus向量库实现CRUD
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文详细介绍了如何使用Java SpringBoot框架集成Milvus向量数据库,并实现了数据的增删改查操作。文章首先介绍了Milvus的基本概念,如数据库、集合和实体,然后逐步演示了如何通过Maven引入Milvus SDK,配置连接信息,创建MilvusClient,以及编写Service和Controller来实现数据的插入、获取和向量检索等功能。最后,文章通过实际的CRUD操作验证了集成效果,并提供了测试URL,帮助读者快速上手。

💡 Milvus 是一款开源向量数据库,适用于大模型领域的向量查询。它支持多种编程语言,本文重点介绍了如何使用Java语言和Spring Boot框架集成Milvus。

⚙️ 集成Milvus需要添加Maven依赖,配置Milvus数据库的IP和端口,并创建MilvusClient。核心代码包括创建Collection、插入数据、通过ID获取记录以及按向量检索等操作。

📝 文章提供了创建Collection、插入数据、查询单条记录和按向量检索相似度的示例代码和测试URL,方便用户进行验证。同时,也提及了向量字段的生成需要通过Embedding模型计算,为后续的深入学习提供了指引。

Milvus是一款开源向量数据库,主要用于在大模型领域做向量查询的相关操作。milvus支持的语言比较多,支持python, Java, Go,node等开发语言。本文主要介绍如何使用Java语言,采用springboot框架集成和调用Milvus数据库。

本文示例使用的milvus版本是 v2.5.4,关于如何安装部署milvus向量数据,请参考上一篇文章:lowcode.blog.csdn.net/article/det…

本文使用Java sdk操作Milvus实现数据的增删改查,需要先对milvus的基本概念有个初步的了解,便于对后面代码的更好理解。

Milvus基本概念

添加maven依赖

创建springboot工程后,在pom.xml文件里引入milvus的sdk

io.milvus milvus-sdk-java 2.5.4

本示例使用的是milvus2.5.4最新版本,Java sdk 接口参考文档:milvus.io/api-referen…

注意使用sdk版本跟milvus版本的对应关系,milvus2.5.x版本建议使用sdk2.5.2以上版本,否则可能会出现一些诡异问题。

配置yml文件

#配置milvus向量数据库的IP和端口,后面构建MilvusClient时需要

server:
port: 8080
milvus:
host: 192.168.3.17
port: 19530

4、创建MilvusClient初始化类

import io.milvus.v2.client.ConnectConfig;

import io.milvus.v2.client.MilvusClientV2;

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 Integer port;

@Bean

public MilvusClientV2 milvusClientV2() {

String uri = "http://"+host+":"+port;

ConnectConfig connectConfig = ConnectConfig.builder()

.uri(uri)

.build();

return new MilvusClientV2(connectConfig);

}

}

5、创建操作向量库的Seivce

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.yuncheng.milvus.TestRecord;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import io.milvus.v2.service.vector.request.GetReq;
import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.GetResp;
import io.milvus.v2.service.vector.response.InsertResp;
import io.milvus.v2.service.vector.response.SearchResp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Component
public class MilvusDemoService {

private static final Logger log = LoggerFactory.getLogger(MilvusDemoService.class);

//类似于mysql中的表,定义一个名称为collection_01的集合
private static final String COLLECTION_NAME = "collection_01";
//为了测试验证方便,向量维度定义2
private static final int VECTOR_DIM = 2;

private final MilvusClientV2 client;

public MilvusDemoService(MilvusClientV2 client) {
this.client = client;
}

/**

CreateCollectionReq.CollectionSchema schema = client.createSchema();

schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.VarChar)
.isPrimaryKey(true)
.autoID(false)
.build());

schema.addField(AddFieldReq.builder()
.fieldName("title")
.dataType(DataType.VarChar)
.maxLength(10000)
.build());

schema.addField(AddFieldReq.builder()
.fieldName("title_vector")
.dataType(DataType.FloatVector)
.dimension(VECTOR_DIM)
.build());

IndexParam indexParam = IndexParam.builder()
.fieldName("title_vector")
.metricType(IndexParam.MetricType.COSINE)
.build();

CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
.collectionName(COLLECTION_NAME)
.collectionSchema(schema)
.indexParams(Collections.singletonList(indexParam))
.build();

client.createCollection(createCollectionReq);
}

/**

InsertReq insertReq = InsertReq.builder()
.collectionName(COLLECTION_NAME)
.data(Collections.singletonList(vector))
.build();
InsertResp resp = client.insert(insertReq);

}

/**

/**

for (List<SearchResp.SearchResult> results : searchResults) {
for (SearchResp.SearchResult result : results) {
log.info("ID="+(String)result.getId() + ",Score="+result.getScore() + ",Result="+result.getEntity().toString());
}
}
return searchResults;
}

}

这里使用到的一个简单的pojo类

public class TestRecord {
private String id;
private String title;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}

}

6、创建Controller类

import com.yuncheng.milvus.service.MilvusDemoService;
import io.milvus.v2.service.vector.response.GetResp;
import io.milvus.v2.service.vector.response.SearchResp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;

@RestController
@RequestMapping("/milvus")
public class MilvusController {
private static final Logger log = LoggerFactory.getLogger(MilvusController.class);

@Autowired
private MilvusDemoService milvusDemoService;

@GetMapping("/createCollection")
public void createCollection() {
milvusDemoService.createCollection();
}

@GetMapping("/insertRecord")
public void insertRecord() throws IOException {
TestRecord record = new TestRecord();
record.setId("5");
record.setTitle("北京是中国的首都,人口有3000多万人");
milvusDemoService.insertRecord(record);
}

@GetMapping("/getRecord")
public GetResp getRecord(@RequestParam(name = "id") String id){
GetResp resp = milvusDemoService.getRecord(id);
log.info("resp = " + resp.getResults);
return resp;
}

@GetMapping("/queryVector")
public List<List<SearchResp.SearchResult>> queryVector() {
List<List<SearchResp.SearchResult>> searchResults = milvusDemoService.queryVector();
return searchResults;
}

}

测试验证CRUD

确保milvus2.5.4向量数据库正常运行,然后启动springboot工程,进行对milvus向量数据库测试验证。

7.1、创建Collection

http://localhost:8080/milvus/createCollection

执行后,登录milvus控制台webUI查看

点击collection名称,查看详细的结构定义,类似于mysql中的表结构定义:

其中,id、title、title_vector字段是程序里定义的字段,另外RowID和Timestamp字段是collection默认自带的字段。

7.2、插入数据

http://localhost:8080/milvus/insertRecord

为了测试方便,本示例写死了测试数据,往milvus中插入了5条数据

7.3、查询单条记录

http://localhost:8080/milvus/getRecord?id=2

返回JSON结果集

{

"getResults": [

{

"entity": {

"title_vector": [1, 2],

"id": "2",

"title": "张三是英国人,他喜欢吃中国火锅"

}

}

]

}

7.4、按向量检索相似度

http://localhost:8080/milvus/queryVector

返回结果集:

[

[

{

"entity": {

"title_vector": [0.8, 1.9],

"id": "4",

"title": "王五是老师,她教学AI算法"

},

"score": 0.9999797,

"id": "4"

},

{

"entity": {

"title_vector": [1, 2],

"id": "2",

"title": "张三是英国人,他喜欢吃中国火锅"

},

"score": 0.99827427,

"id": "2"

},

{

"entity": {

"title_vector": [1, 2],

"id": "1",

"title": "我是中国人,我喜欢吃火锅"

},

"score": 0.99827427,

"id": "1"

}

]

]

其中,score为向量相似度分值,如果score=1,则表示完全一样,score小于1,表示接近。这里为了测试方面,插入数据时,在向量字段里写死了几个固定的List值,真实的业务场景中,要通过Embedding模型计算生成,后续文章中介绍如何调用AI中的Embedding服务,生成向量化的float值。

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Milvus Java Spring Boot 向量数据库 CRUD
相关文章