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

相关推荐
小堂子这厢有礼了2 分钟前
Chet.QuartzNet.UI v2.3.0 大更新!表格重构 + 系统配置 + 分析页全面升级!
前端·后端·ui·重构·c#·vue
cfm_29146 分钟前
SpringBoot自定义Starter
java·spring boot·后端
触底反弹8 分钟前
⚡ Promise.all 性能优化:让 Agent 的工具调用飞起来
javascript·人工智能·后端
霸道流氓气质11 分钟前
Windows 本地搭建 CDC 全链路测试环境(Kafka+Canel+binlog+SpringBoot)
windows·spring boot·kafka
程序员爱钓鱼13 分钟前
Rust 控制流 if 详解:条件判断与 if 表达式
前端·后端·rust
Demon_Hao20 分钟前
Spring Boot 4、JDK 25 与 GraalVM:Java 云原生进化,能否撼动 Go 的地位?
java·spring boot·云原生
kyle~1 小时前
Swagger ---基于 描述文件 生成 交互式API文档 的工具
前端·后端·规格说明书·说明文档
江畔柳前堤9 小时前
GO01-Go 语言与主流编程语言深度对比
开发语言·人工智能·后端·微服务·云原生·golang·go
世界哪有真情10 小时前
拿人类意识卡 AI?等于用 bug 验收正式产品
前端·人工智能·后端
Csvn12 小时前
Day 3:LIKE 与模式匹配 — 让查询学会"模糊搜索"
后端·sql