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数据库的实现

相关推荐
uzong2 小时前
技术故障复盘模版
后端
GetcharZp2 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程2 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研2 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi3 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
一只爱撸猫的程序猿3 小时前
使用Spring AI配合MCP(Model Context Protocol)构建一个"智能代码审查助手"
spring boot·aigc·ai编程
甄超锋4 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
阿华的代码王国4 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy4 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack4 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt