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、获取文件

plain 复制代码
`wget https://github.com/milvus-io/milvus/releases/download/v2.1.4/milvus-standalone-docker-compose.yml -O docker-compose.yml`

5、启动docker镜像

plain 复制代码
`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的组件工具

plain 复制代码
`<!-- 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.客户端初始化

初始化客户端使用实例,放入容器

plain 复制代码
`@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.代码示例集合
plain 复制代码
`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

plain 复制代码
`milvus:`
`
host: 10.0.3.65`
`
port: 19530`

logging:

level:

io.milvus.client: debug
测试用例代码

plain 复制代码
`@SpringBootTest`
`
@Slf4j`
`
class MilvusConfigTest {`
复制代码
@Autowired
MilvusClient milvusClient;

@Test
void test() {
    R&lt;QueryResults&gt; 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&lt;RpcStatus&gt; collection = milvusClient.createCollection(createCollectionReq);
    log.info("collection:{}", JSONUtil.toJsonStr(collection));
}


/**
 * 插入数据
 *
 * @return
 */
@Test
public void insertPrepare() {

    List&lt;String&gt; content_array = new ArrayList&lt;&gt;();
    List&lt;List&lt;Float&gt;&gt; vector_array = new ArrayList&lt;&gt;();

    for (int i = 0; i &lt; 5; i++) {
        content_array.add("test" + i);
        vector_array.add(Arrays.asList(1.1f + i * 1f, 2.2f + i * 2f));
    }

    List&lt;InsertParam.Field&gt; fields = new ArrayList&lt;&gt;();
    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&lt;MutationResult&gt; insert = milvusClient.insert(insertParam);
    log.info("insert:{}", JSONUtil.toJsonStr(insert));
}


@Test
public void searchTallestSimilarity() {
    loadCollection();
    List&lt;List&lt;Float&gt;&gt; list = new ArrayList&lt;&gt;();
    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&lt;SearchResults&gt; search = milvusClient.search(searchParam);
    List&lt;String&gt; returnList = Lists.newArrayList();
    SearchResultsWrapper wrapper = new SearchResultsWrapper(search.getData().getResults());
    for (int i = 0; i &lt; list.size(); i++) {
        List&lt;?&gt; fieldData = wrapper.getFieldData(PushMaterielsConst.Field.CONTENT, i);
        for (int j = 0; j &lt; fieldData.size(); j++) {
            returnList.add((String) fieldData.get(j));
        }
    }
    log.info("----搜索结果------{}",JSONUtil.toJsonStr(returnList));
}

public void loadCollection() {
    R&lt;RpcStatus&gt; response = milvusClient.loadPartitions(
            LoadPartitionsParam
                    .newBuilder()
                    //集合名称
                    .withCollectionName(PushMaterielsConst.COLLECTION_NAME)
                    //需要加载的分区名称
                    .withPartitionNames(Lists.newArrayList(PushMaterielsConst.PARTITION_NAME))
                    .build());
    log.info("Milvus数据加载到内存状态:{}", response.getStatus());
}

}

上述为springboot集成Milvus数据库的实现

相关推荐
Albert Edison3 小时前
【最新版】IntelliJ IDEA 2025 创建 SpringBoot 项目
java·spring boot·intellij-idea
Piper蛋窝4 小时前
深入 Go 语言垃圾回收:从原理到内建类型 Slice、Map 的陷阱以及为何需要 strings.Builder
后端·go
六毛的毛7 小时前
Springboot开发常见注解一览
java·spring boot·后端
AntBlack7 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
31535669137 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端
uzong7 小时前
curl案例讲解
后端
开开心心就好8 小时前
免费PDF处理软件,支持多种操作
运维·服务器·前端·spring boot·智能手机·pdf·电脑
一只叫煤球的猫8 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端
猴哥源码8 小时前
基于Java+SpringBoot的农事管理系统
java·spring boot
大鸡腿同学9 小时前
身弱武修法:玄之又玄,奇妙之门
后端