本文主要是介绍SpringBoot集成Milvus实现数据增删改查功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo...
Milvus是一款开源向量数据库,主要用于在大模型领域做向量查询的相关操作。milvus支持的语言比较多,支持python, Java, Go,node等开发语言。本文主要介绍如何使用Java语言,采用spri编程ngboot框架集成和调用Milvus数据库。
本文示例使用的milvus版本是 v2.5.4,关于如何安装部署milvus向量数据,请参考上一篇文章:https://lowcode.blog.csdn.net/article/details/145552128
本文使用Java sdk操作Milvus实现数据的增删改查,需要先对milvus的基本概念有个初步的了解,便于对后面代码的更好理解。milvus更多帮助请参考官方文档:https://milvus.io/docs/overview.md
1、Milvus基本概念
- 数据库Database:与传统的数据库引擎mysql类似,你也可以在 Milvus 中创建数据库,并为特定用户分配权限来管理它们。然后,此类用户有权管理数据库中的集合。一个 Milvus 集群最多支持 64 个数据库。Milvus 集群附带一个名为 'default' 的默认数据库。除非另有指定,否则将在 default 数据库中创建集合。
- 集合Collection :在 Milvus 中,你可以创建多个集合来管理数据,并将数据作为实体插入到集合中。Collection 和 entity 类似于关系数据库中的 table 和 records。集合是具有固定列和变体行的二维表。每列表示一个字段,每行表示一个实体。Collection 是具有固定列和变体行的二维表。每列表示一个字段,每行表示一个实体。需要Schema来实现此类结构数据管理,要插入的每个实体都必须满足Schema中定义的约束。
- 实体Entity :在 Milvus 中,Entity 是指 Collection 中共享相同 Schema 的数据记录,一行中每个字段的数据构成一个 Entity。因此,同一 Collection 中的 Entities 具有相同的属性(例如字段名称、数据类型和其他约束)。将 Entity 插入 Collection 时,要插入的 Entity 只有在包含 Schema 中定义的所有字段时才能成功添加。Milvus 还支持动态字段,以保持 Collection 的可扩展性。启用动态字段后,您可以将 Schema 中未定义的字段插入到 Collection 中。这些字段和值将作为键值对存储在名为 $meta 的保留字段中。
2、添加maven依赖
创建springboot工程后,在pom.XML文件里引入milvus的sdk
<dependency>
<groupId>io.milvus</groupId>
<artifactId>milvus-sdk-java</artifacthttp://www.chinasem.cnId>
<version>2.5.4</version>
</dependency>本示例使用的是milvus2.5.4最新版本,Java sdk 接口参考文档:https://milvus.io/api-reference/java/v2.5.x/About.md
注意使用sdk版本跟milvus版本的对应关系,milvus2.5.x版本建议使用sdk2.5.2以上版本,否则可能会出现一些诡异问题。
3、配置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://"+hosAvYhwZTHgUt+":"+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.serviphpce.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; } /** * 创建一个Collection */ public void createCollection() { 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); } /** * 往collection中插入一条数据 */ public void insertRecord(TestRecord record) { JsonObject vector = new JsonObject(); vector.addProperty("id", record.getId()); vector.addProperty("title", record.getTitle()); List<Float> vectorList = new ArrayList<>(); //为了模拟测试,向量写死2个 vectorList.add(2.8f); vectorList.add(3.9f); Gson gson = new Gson(); vector.add("title_vector", gson.toJsonTree(vectorList)); InsertReq insertReq = InsertReq.builder() .collectionName(COLLECTION_NAME) .data(Collections.singletonList(vector)) .build(); InsertResp resp = client.insert(insertReq); } /** * 通过ID获取记录 */ public GetResp getRecord(String id) { GetReq getReq = GetReq.builder() .collectionName(COLLECTION_NAME) .ids(Collections.singletonList(id)) .build(); GetResp resp = client.get(getReq); return resp; } /** * 按照向量检索,找到相似度最近的topK */ public List<List<SearchResp.SearchResult>> queryVector() { SearchResp searchR = client.search(SearchReq.builder() .collectionName(COLLECTION_NAME) .data(Collections.singletonList(new FloatVec(new float[]{0.9f, 2.1f}))) .topK(3) .outputFields(Collections.singletonList("*")) .build()); List<List<SearchResp.SearchResult>> searchResults = searchR.getSearchResults(); 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 getTphpitle() {
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;
}
}7、测试验证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<Float>值,真实的业务场景中,要通过Embedding模型计算生成,后续文章中介绍如何调用AI中的Embedding服务,生成向量化的float值。
到此这篇关于SpringBoot集成Milvus,实现数据增删改查的文章就介绍到这了,更多相关SpringBoot集成Milvus内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!
这篇关于SpringBoot集成Milvus实现数据增删改查功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!