SpringBoot集成Milvus|(实现向量的存储和查询)
此文章为转载文章: 原文链接
文章目录
- SpringBoot集成Milvus|(实现向量的存储和查询)
- 前言
- 一、Milvus介绍
- 二、Milvus数据库安装
- 1.Milvus安装环境准备(centos7)
- 2.Milvus客户端安装
- 3.attu新建Milvus集合
- 三、Milvus集成
- 1.依赖引入
- 2.客户端初始化
- 3.代码创建集合示例
- 总结
原文链接: SpringBoot集成Milvus|(实现向量的存储和查询)
前言
随着互联网不断发展,电子邮件、论文、物联网传感数据、社交媒体照片、蛋白质分子结构等非结构化数据已经变得越来越普遍。如果想要使用计算机来处理这些数据,需要使用 embedding 技术将这些数据转化为向量。随后,Milvus 会存储这些向量,并为其建立索引。Milvus 能够根据两个向量之间的距离来分析他们的相关性。如果两个向量十分相似,这说明向量所代表的源数据也十分相似
一、Milvus介绍
Milvus 是一款云原生向量数据库,它具备高可用、高性能、易拓展的特点,用于海量向量数据的实时召回。
Milvus 基于 FAISS、Annoy、HNSW 等向量搜索库构建,核心是解决稠密向量相似度检索的问题。在向量检索库的基础上,Milvus 支持数据分区分片、数据持久化、增量数据摄取、标量向量混合查询、time travel 等功能,同时大幅优化了向量检索的性能,可满足任何向量检索场景的应用需求。通常,建议用户使用 Kubernetes 部署 Milvus,以获得最佳可用性和弹性。
二、Milvus数据库安装
1.Milvus安装环境准备(centos7)
1、服务器需要部署docker以及docker-compose 2、新建一个工作目录 3、获取Milvus的安装启动YAML文件 4、获取文件
wget https://github.com/milvus-io/milvus/releases/download/v2.1.4/milvus-standalone-docker-compose.yml -O docker-compose.yml
5、启动docker镜像
docker-compose up -d
6、启动后容器情况
7、停止Milvus容器
docker-compose down
2.Milvus客户端安装
1、在docker仓库中找到Milvus对应版本的客户端镜像
2、拉取镜像;docker pull zilliz/attu:v2.1.0
3、运行attu
docker run -itd --restart=always -p 13000:3000 -e HOST_URL=http://{ip}:13000 -e MILVUS_URL={ip}:19530 zilliz/attu:v2.1.0
ip为部署ip
4、浏览器登陆访问:http://{ip}:13000
三、Milvus集成
1.依赖引入
java操作Milvus的组件工具
<!-- milvus向量数据库 -->
<dependency>
<groupId>io.milvus</groupId>
<artifactId>milvus-sdk-java</artifactId>
<version>2.2.4</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
2.客户端初始化
初始化客户端使用实例,放入容器
@Configuration public class MilvusConfig {
@Value("${milvus.host}") private String host; @Value("${milvus.port}") private Integer port; @Bean public MilvusServiceClient milvusServiceClient() { return new MilvusServiceClient( ConnectParam.newBuilder() .withHost(host) .withPort(port) .build()); }
}
3.代码示例集合
public class PushMaterielsConst {
/**
* 集合名称(库名)
*/
public static final String COLLECTION_NAME = “content3”;
public static final String PARTITION_NAME = "content3_partion";
/**
* 分片数量
*/
public static final Integer SHARDS_NUM = 1;
/**
* 分区数量
*/
public static final Integer PARTITION_NUM = 1;
/**
* 分区前缀
*/
public static final String PARTITION_PREFIX = "shards_";
/**
* 向量值长度
*/
public static final Integer FEATURE_DIM = 256;
public static final Boolean TRUE = true;
/**
* 字段
*/
public static class Field {
/**
* 主键idID
*/
public static final String ID = "id";
/**
* 文本id
*/
public static final String CONTENT = "content";
/**
* 向量值
*/
public static final String CONTENT_INTRO = "content_intro";
}
}
4.测试用例
yml
milvus:
host: 10.0.3.65
port: 19530
logging:
level:
io.milvus.client: debug
测试用例代码
@SpringBootTest
@Slf4j
class MilvusConfigTest {
@Autowired
MilvusClient milvusClient;
@Test
void test() {
R<QueryResults> query = milvusClient.query(QueryParam.newBuilder().withCollectionName("content3").build());
log.info("query:{}", JSONUtil.toJsonStr(query));
}
@Test
public void creatCollection() {
FieldType fieldType1 = FieldType.newBuilder()
.withName(PushMaterielsConst.Field.ID)
.withDataType(DataType.Int64)
.withPrimaryKey(true)
.withAutoID(true)
.build();
FieldType fieldType2 = FieldType.newBuilder()
.withName(PushMaterielsConst.Field.CONTENT)
.withDataType(DataType.VarChar)
.withMaxLength(255)
.build();
FieldType fieldType3 = FieldType.newBuilder()
.withName(PushMaterielsConst.Field.CONTENT_INTRO)
.withDataType(DataType.FloatVector)
.withDimension(2)
.build();
CreateCollectionParam createCollectionReq = CreateCollectionParam.newBuilder()
.withCollectionName(PushMaterielsConst.COLLECTION_NAME)
.withDescription("user content search")
.withShardsNum(2)
.addFieldType(fieldType1)
.addFieldType(fieldType2)
.addFieldType(fieldType3)
.build();
R<RpcStatus> collection = milvusClient.createCollection(createCollectionReq);
log.info("collection:{}", JSONUtil.toJsonStr(collection));
}
/**
* 插入数据
*
* @return
*/
@Test
public void insertPrepare() {
List<String> content_array = new ArrayList<>();
List<List<Float>> vector_array = new ArrayList<>();
for (int i = 0; i < 5; i++) {
content_array.add("test" + i);
vector_array.add(Arrays.asList(1.1f + i * 1f, 2.2f + i * 2f));
}
List<InsertParam.Field> fields = new ArrayList<>();
fields.add(new InsertParam.Field(PushMaterielsConst.Field.CONTENT, content_array));
fields.add(new InsertParam.Field(PushMaterielsConst.Field.CONTENT_INTRO, vector_array));
InsertParam insertParam = InsertParam.newBuilder()
.withCollectionName(PushMaterielsConst.COLLECTION_NAME)
.withPartitionName(PushMaterielsConst.PARTITION_NAME)
.withFields(fields)
.build();
R<MutationResult> insert = milvusClient.insert(insertParam);
log.info("insert:{}", JSONUtil.toJsonStr(insert));
}
@Test
public void searchTallestSimilarity() {
loadCollection();
List<List<Float>> list = new ArrayList<>();
list.add(Arrays.asList(1.1f, 2.2f));
SearchParam searchParam = SearchParam.newBuilder()
//集合名称
.withCollectionName(PushMaterielsConst.COLLECTION_NAME)
.withPartitionNames(Arrays.asList(PushMaterielsConst.PARTITION_NAME))
//计算方式
// 欧氏距离 (L2)
// 内积 (IP)
.withMetricType(MetricType.L2)
.withOutFields(Arrays.asList(PushMaterielsConst.Field.CONTENT))
//返回多少条结果
.withTopK(5)
//搜索的向量值
.withVectors(list)
//搜索的Field
.withVectorFieldName(PushMaterielsConst.Field.CONTENT_INTRO)
.withParams("{\"content\":\"test56\"}")
.build();
R<SearchResults> search = milvusClient.search(searchParam);
List<String> returnList = Lists.newArrayList();
SearchResultsWrapper wrapper = new SearchResultsWrapper(search.getData().getResults());
for (int i = 0; i < list.size(); i++) {
List<?> fieldData = wrapper.getFieldData(PushMaterielsConst.Field.CONTENT, i);
for (int j = 0; j < fieldData.size(); j++) {
returnList.add((String) fieldData.get(j));
}
}
log.info("----搜索结果------{}",JSONUtil.toJsonStr(returnList));
}
public void loadCollection() {
R<RpcStatus> response = milvusClient.loadPartitions(
LoadPartitionsParam
.newBuilder()
//集合名称
.withCollectionName(PushMaterielsConst.COLLECTION_NAME)
//需要加载的分区名称
.withPartitionNames(Lists.newArrayList(PushMaterielsConst.PARTITION_NAME))
.build());
log.info("Milvus数据加载到内存状态:{}", response.getStatus());
}
}
上述为springboot集成Milvus数据库的实现