【SpringBoot】SpringBoot整合Milvus

这篇具有很好参考价值的文章主要介绍了【SpringBoot】SpringBoot整合Milvus。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、什么是Milvus?

Milvus,一个开源的高性能向量数据库,它在各种应用场景中展现出强大的性能和灵活性。
在许多现代应用中,处理和分析大规模向量数据变得越来越重要。例如,在图像和视频搜索、推荐系统、自然语言处理和生物信息学等领域,向量数据被广泛应用。

二、项目背景

在公司推荐系统中,我们需要根据用户的历史行为和兴趣,为其推荐相关的内容。于是将用户和内容表示为向量,并使用 Milvus 进行相似度匹配。通过将用户向量和内容向量存储在 Milvus 中,并利用其高效的相似度查询功能,我们可以快速找到与用户兴趣最匹配的内容,并进行个性化推荐。

向量的生成由spark任务生成数据并写入,本文只写SpringBoot集成Milvus实现数据查询部分,面向C端,性能已测

三、Maven依赖引入

开始使用的是1.x版本,后来由于2.x新增了过滤筛选功能,升级了版本为2.2.3,1版本和2版本查询还是有一些区别,建议采用2版本

<dependency>
    <groupId>io.milvus</groupId>
    <artifactId>milvus-sdk-java</artifactId>
    <version>2.2.3</version>
</dependency>

四、自动配置

@Configuration
public class MilvusConfiguration {

    /**
     *  milvus ip addr
     */
    @Value("${milvus.config.ipAddr}")
    private String ipAddr;

    /**
     * milvus   port
     */
    @Value("${milvus.config.port}")
    private Integer  port;

    @Bean
    @Scope("singleton")
    public MilvusServiceClient getMilvusClient() {
        return getMilvusFactory().getMilvusClient();
    }

    @Bean(initMethod = "init", destroyMethod = "close")
    public MilvusRestClientFactory getMilvusFactory() {
        return  MilvusRestClientFactory.build(ipAddr, port);
    }
}

五、milvus Rest client 封装

public class MilvusRestClientFactory {

    private static String  IP_ADDR;

    private static Integer PORT ;

    private MilvusServiceClient milvusServiceClient;

    private ConnectParam.Builder  connectParamBuilder;


    private static MilvusRestClientFactory milvusRestClientFactory = new MilvusRestClientFactory();

    private MilvusRestClientFactory(){

    }

    public static MilvusRestClientFactory build(String ipAddr, Integer  port) {
        IP_ADDR = ipAddr;
        PORT = port;
        return milvusRestClientFactory;
    }

    private ConnectParam.Builder connectParamBuilder(String host, int port) {
        return  ConnectParam.newBuilder().withHost(host).withPort(port);
    }



    public void init() {
        connectParamBuilder =  connectParamBuilder(IP_ADDR,PORT);
        ConnectParam connectParam = connectParamBuilder.build();
        milvusServiceClient =new MilvusServiceClient(connectParam);
    }


    public MilvusServiceClient getMilvusClient() {
        return milvusServiceClient;
    }


    public void close() {
        if (milvusServiceClient != null) {
            try {
                milvusServiceClient.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

六、查询

写入数据不同,获取结果不同,我这里最后获取的是Long类型的数据集合,仅供参考

同步搜索milvus

/**
 * 同步搜索milvus
 * @param collectionName 表名
 * @param vectors 查询向量
 * @param topK 最相似的向量个数
 * @return
 */
public List<Long> search(String collectionName, List<List<Float>> vectors, Integer topK) {

    Assert.notNull(collectionName, "collectionName  is null");
    Assert.notNull(vectors, "vectors is null");
    Assert.notEmpty(vectors, "vectors is empty");
    Assert.notNull(topK, "topK is null");
    int nprobeVectorSize = vectors.get(0).size();
    String paramsInJson = "{"nprobe": " + nprobeVectorSize + "}";
    SearchParam searchParam =
            SearchParam.newBuilder().withCollectionName(collectionName)
                    .withParams(paramsInJson)
                    .withMetricType(MetricType.IP)
                    .withVectors(vectors)
                    .withVectorFieldName("embedding")
                    .withTopK(topK)
                    .build();

    R<SearchResults> searchResultsR = milvusServiceClient.search(searchParam);
    SearchResults searchResultsRData = searchResultsR.getData();
    List<Long> topksList = searchResultsRData.getResults().getIds().getIntId().getDataList();
    return topksList;
}

同步搜索milvus,增加过滤条件搜索

/**
 * 同步搜索milvus,增加过滤条件搜索
 *
 * @param collectionName 表名
 * @param vectors 查询向量
 * @param topK 最相似的向量个数
 * @param exp 过滤条件:status=1
 * @return
 */
public List<Long> search(String collectionName, List<List<Float>> vectors, Integer topK, String exp) {
    Assert.notNull(collectionName, "collectionName  is null");
    Assert.notNull(vectors, "vectors is null");
    Assert.notEmpty(vectors, "vectors is empty");
    Assert.notNull(topK, "topK is null");
    Assert.notNull(exp, "exp is null");
    int nprobeVectorSize = vectors.get(0).size();
    String paramsInJson = "{"nprobe": " + nprobeVectorSize + "}";
    SearchParam searchParam =
            SearchParam.newBuilder().withCollectionName(collectionName)
                    .withParams(paramsInJson)
                    .withMetricType(MetricType.IP)
                    .withVectors(vectors)
                    .withExpr(exp)
                    .withVectorFieldName("embedding")
                    .withTopK(topK)
                    .build();

    R<SearchResults> searchResultsR = milvusServiceClient.search(searchParam);
    SearchResults searchResultsRData = searchResultsR.getData();
    List<Long> topksList = searchResultsRData.getResults().getIds().getIntId().getDataList();
    return topksList;
}

异步搜索milvus:针对实时结果要求不高的场景

/**
 * 异步搜索milvus
 *
 * @param collectionName 表名
 * @param vectors 查询向量
 * @param partitionList 最相似的向量个数
 * @param topK
 * @return
 */
public List<Long> searchAsync(String collectionName, List<List<Float>> vectors,
                              List<String> partitionList, Integer topK) throws ExecutionException, InterruptedException {

    Assert.notNull(collectionName, "collectionName  is null");
    Assert.notNull(vectors, "vectors is null");
    Assert.notEmpty(vectors, "vectors is empty");
    Assert.notNull(partitionList, "partitionList is null");
    Assert.notEmpty(partitionList, "partitionList is empty");
    Assert.notNull(topK, "topK is null");
    int nprobeVectorSize = vectors.get(0).size();
    String paramsInJson = "{"nprobe": " + nprobeVectorSize + "}";
    SearchParam searchParam =
            SearchParam.newBuilder().withCollectionName(collectionName)
                    .withParams(paramsInJson)
                    .withVectors(vectors)
                    .withTopK(topK)
                    .withPartitionNames(partitionList)
                    .build();
    ListenableFuture<R<SearchResults>> listenableFuture = milvusServiceClient.searchAsync(searchParam);

    List<Long> resultIdsList = listenableFuture.get().getData().getResults().getTopksList();

    return resultIdsList;
}

获取分区集合文章来源地址https://www.toymoban.com/news/detail-532062.html

/**
 * 获取分区集合
 * @param collectionName 表名
 * @return
 */
public List<String> getPartitionsList(String collectionName) {
    Assert.notNull(collectionName, "collectionName  is null");
    ShowPartitionsParam searchParam = ShowPartitionsParam.newBuilder().withCollectionName(collectionName).build();
    List<ByteString> byteStrings = milvusServiceClient.showPartitions(searchParam).getData().getPartitionNamesList().asByteStringList();
    List<String> partitionList = Lists.newLinkedList();
    byteStrings.forEach(s -> {
        partitionList.add(s.toStringUtf8());
    });
    return partitionList;
}

七、yml配置数据

milvus:
  config:
    ipAddr: xxx.xxx.xxx.xxx
    port: 19531

到了这里,关于【SpringBoot】SpringBoot整合Milvus的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接

    系列文章: SpringBoot + Vue前后端分离项目实战 || 一:Vue前端设计 SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接 SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接 SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现 SpringBoot + Vue前后

    2024年02月12日
    浏览(71)
  • SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接

    系列文章: SpringBoot + Vue前后端分离项目实战 || 一:Vue前端设计 SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接 SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接 SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现 SpringBoot + Vue前后

    2024年02月11日
    浏览(66)
  • spring boot es | spring boot 整合elasticsearch | spring boot整合多数据源es

    目录 Spring Boot与ES版本对应 Maven依赖 配置类 使用方式 @Test中注入方式 @Component中注入方式 查询文档 实体类 通过ElasticsearchRestTemplate查询 通过JPA查询 保存文档 参考链接 项目组件版本: Spring Boot:2.2.13.RELEASE Elasticsearch:6.8.0 JDK:1.8.0_66 Tips: 主要看第3列和第5列,根据ES版本选择

    2023年04月18日
    浏览(59)
  • 【Spring Boot】Spring Boot整合多数据源

    在实际的开发工作中,我们经常会遇到需要整合多个数据源的情况,比如同时连接多个数据库、读写分离、跨数据库查询等。本文将介绍如何使用Spring Boot来实现多数据源的整合,对于刚刚接触开发的小伙伴可能有一些帮助。 在一个应用程序中使用多个数据源意味着我们需要

    2024年02月10日
    浏览(44)
  • Spring Boot进阶(96):轻松上手:实战Spring Boot整合Docker

      Docker 是一个开源的应用程序容器化工具,它可以将应用程序和依赖组件打包到一个容器中,实现应用程序的快速部署和运行。Spring Boot 是一个快速开发应用程序的框架,使用 Spring Boot 可以快速构建各种各样的应用程序。本文将介绍如何使用 Spring Boot 整合 Docker,实现应用

    2024年02月07日
    浏览(56)
  • Spring Boot进阶(98):【实战经验】Spring Boot如何轻松整合Jenkins?

      Jenkins是一款流行的开源持续集成工具,通过Jenkins可以对项目进行持续集成、自动化部署等操作,提高开发效率和代码质量。Spring Boot作为一款轻量级的开发框架,具有快速构建应用、简化配置等众多优点,与Jenkins的结合可以进一步提高开发效率和项目质量。   那么,

    2024年02月06日
    浏览(59)
  • Spring Boot进阶(19):Spring Boot 整合ElasticSearch | 超级详细,建议收藏

            ElasticSearch是一款基于Lucene的开源搜索引擎,具有高效、可扩展、分布式的特点,可用于全文搜索、日志分析、数据挖掘等场景。Spring Boot作为目前最流行的微服务框架之一,也提供了对ElasticSearch的支持。本篇文章将介绍如何在Spring Boot项目中整合ElasticSearch,并展

    2024年02月06日
    浏览(46)
  • 六、Spring/Spring Boot整合ActiveMQ

    2.1 applicationContext.xml 路径:src/main/resources/applicationContext.xml 2.2 生产者 2.3 消费者 3.1 applicationContext.xml 路径:src/main/resources/applicationContext.xml 3.2 生产者 和队列的代码一样,只是在配置文件里面改了destination 3.3 消费者 和队列的代码一样,只是在配置文件里面改了destination 实现

    2024年02月22日
    浏览(51)
  • Spring Boot 实战 | Spring Boot整合JPA常见问题解决方案

    专栏集锦,大佬们可以收藏以备不时之需: Spring Cloud 专栏: Python 专栏: Redis 专栏: TensorFlow 专栏: Logback 专栏: 量子计算: 量子计算 | 解密著名量子算法Shor算法和Grover算法 AI机器学习实战: AI机器学习实战 | 使用 Python 和 scikit-learn 库进行情感分析 AI机器学习 | 基于lib

    2024年02月04日
    浏览(61)
  • [Spring boot] Spring boot 整合RabbitMQ实现通过RabbitMQ进行项目的连接

     🍳作者:天海奈奈 💭眼过千遍不如手锤一遍:推荐一款模拟面试,斩获大厂 o f f e r ,程序员的必备刷题平台 − − 牛客网  👉🏻点击开始刷题之旅 目录 什么是RabbitMQ   消息队列:接受并转发消息,类似于快递公司 消息队列的优点 消息队列的特性 RabbitMQ特点 RabbitMQ核

    2024年01月24日
    浏览(84)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包