最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot整合Milvus的實(shí)現(xiàn)

 更新時(shí)間:2023年07月04日 10:40:38   作者:楊慕晚  
本文主要介紹了SpringBoot整合Milvus的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

什么是Milvus?

Milvus,一個(gè)開(kāi)源的高性能向量數(shù)據(jù)庫(kù),它在各種應(yīng)用場(chǎng)景中展現(xiàn)出強(qiáng)大的性能和靈活性。
在許多現(xiàn)代應(yīng)用中,處理和分析大規(guī)模向量數(shù)據(jù)變得越來(lái)越重要。例如,在圖像和視頻搜索、推薦系統(tǒng)、自然語(yǔ)言處理和生物信息學(xué)等領(lǐng)域,向量數(shù)據(jù)被廣泛應(yīng)用。

項(xiàng)目背景

在公司推薦系統(tǒng)中,我們需要根據(jù)用戶的歷史行為和興趣,為其推薦相關(guān)的內(nèi)容。于是將用戶和內(nèi)容表示為向量,并使用 Milvus 進(jìn)行相似度匹配。通過(guò)將用戶向量和內(nèi)容向量存儲(chǔ)在 Milvus 中,并利用其高效的相似度查詢功能,我們可以快速找到與用戶興趣最匹配的內(nèi)容,并進(jìn)行個(gè)性化推薦。

向量的生成由spark任務(wù)生成數(shù)據(jù)并寫入,本文只寫SpringBoot集成Milvus實(shí)現(xiàn)數(shù)據(jù)查詢部分,面向C端,性能已測(cè)

Maven依賴引入

開(kāi)始使用的是1.x版本,后來(lái)由于2.x新增了過(guò)濾篩選功能,升級(jí)了版本為2.2.3,1版本和2版本查詢還是有一些區(qū)別,建議采用2版本

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

自動(dòng)配置

@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();
? ? ? ? ? ? }
? ? ? ? }
? ? }
}

查詢

寫入數(shù)據(jù)不同,獲取結(jié)果不同,我這里最后獲取的是Long類型的數(shù)據(jù)集合,僅供參考

同步搜索milvus

/**
?* 同步搜索milvus
?* @param collectionName 表名
?* @param vectors 查詢向量
?* @param topK 最相似的向量個(gè)數(shù)
?* @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,增加過(guò)濾條件搜索

/**
?* 同步搜索milvus,增加過(guò)濾條件搜索
?*
?* @param collectionName 表名
?* @param vectors 查詢向量
?* @param topK 最相似的向量個(gè)數(shù)
?* @param exp 過(guò)濾條件: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:針對(duì)實(shí)時(shí)結(jié)果要求不高的場(chǎng)景

/**
?* 異步搜索milvus
?*
?* @param collectionName 表名
?* @param vectors 查詢向量
?* @param partitionList 最相似的向量個(gè)數(shù)
?* @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;
}

獲取分區(qū)集合

/**
 * 獲取分區(qū)集合
 * @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配置數(shù)據(jù)

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

到此這篇關(guān)于SpringBoot整合Milvus的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot整合Milvus內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java獲取兩個(gè)List集合的交集代碼示例

    java獲取兩個(gè)List集合的交集代碼示例

    這篇文章主要給大家介紹了關(guān)于java獲取兩個(gè)List集合交集的相關(guān)資料,我們可以使用Stream操作來(lái)對(duì)集合進(jìn)行一系列的操作,其中包括求交集,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • 一文詳解SpringBoot如何切換Redis的DB

    一文詳解SpringBoot如何切換Redis的DB

    這篇文章主要為大家詳細(xì)介紹了Spring Redis動(dòng)態(tài)切換數(shù)據(jù)庫(kù)的核心機(jī)制,并指出僅調(diào)用setDatabase()和resetConnection()無(wú)法真正切換數(shù)據(jù)庫(kù)的根本原因,感興趣的小伙伴可以了解下
    2025-12-12
  • springboot使用過(guò)濾器詳解

    springboot使用過(guò)濾器詳解

    本文主要介紹了過(guò)濾器的基本概念,過(guò)濾器的生命周期,以及如何通過(guò)注解方式和非注解方式實(shí)現(xiàn)過(guò)濾器,過(guò)濾器是客戶端與服務(wù)器資源文件之間的一道過(guò)濾網(wǎng),能夠幫助我們過(guò)濾不符合要求的請(qǐng)求,通常用作Session校驗(yàn)
    2024-10-10
  • java模擬TCP通信實(shí)現(xiàn)客戶端上傳文件到服務(wù)器端

    java模擬TCP通信實(shí)現(xiàn)客戶端上傳文件到服務(wù)器端

    這篇文章主要為大家詳細(xì)介紹了java模擬TCP通信實(shí)現(xiàn)客戶端上傳文件到服務(wù)器端,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • MyBatis使用CASE WHEN進(jìn)行批量更新的高效寫法

    MyBatis使用CASE WHEN進(jìn)行批量更新的高效寫法

    當(dāng)我們使用mybatis的時(shí)候,可能經(jīng)常會(huì)碰到一批數(shù)據(jù)的批量更新問(wèn)題,因?yàn)槿绻粭l數(shù)據(jù)一更新,那每一條數(shù)據(jù)就需要涉及到一次數(shù)據(jù)庫(kù)的操作,包括網(wǎng)絡(luò)IO以及磁盤IO,可想而知,這個(gè)效率是非常低下的,那么今天我們就來(lái)總結(jié)一下,如何使用mybatis做批量更新,需要的朋友可以參考下
    2025-10-10
  • Java使用ScriptEngine動(dòng)態(tài)執(zhí)行代碼(附Java幾種動(dòng)態(tài)執(zhí)行代碼比較)

    Java使用ScriptEngine動(dòng)態(tài)執(zhí)行代碼(附Java幾種動(dòng)態(tài)執(zhí)行代碼比較)

    這篇文章主要介紹了Java使用ScriptEngine動(dòng)態(tài)執(zhí)行代碼,并且分享Java幾種動(dòng)態(tài)執(zhí)行代碼比較,需要的朋友可以參考下
    2021-04-04
  • Flink部署集群整體架構(gòu)源碼分析

    Flink部署集群整體架構(gòu)源碼分析

    這篇文章主要為大家介紹了Flink部署集群及整體架構(gòu)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Javaweb動(dòng)態(tài)開(kāi)發(fā)最重要的Servlet詳解

    Javaweb動(dòng)態(tài)開(kāi)發(fā)最重要的Servlet詳解

    動(dòng)態(tài)web的核心是Servlet,由tomcat解析并執(zhí)行,本質(zhì)是Java中的一個(gè)類(面向?qū)ο螅┻@個(gè)類的功能十分強(qiáng)大幾乎可以完成全部功能,在Java規(guī)范中只有Servlet實(shí)現(xiàn)類實(shí)例化的對(duì)象才能被瀏覽器訪問(wèn),所以掌握Servlet具有重要意義
    2022-08-08
  • java二分查找插入法

    java二分查找插入法

    當(dāng)你需要構(gòu)建一個(gè)大的有序隊(duì)列,用插入發(fā)太慢了,可以先用二分查找法,找到在隊(duì)列要插入的位置,把數(shù)后移一下,然后放進(jìn)去。比較效率,下面是java使用示例,需要的朋友可以參考下
    2014-03-03
  • 從零開(kāi)始手寫JDBC連接數(shù)據(jù)庫(kù)的詳細(xì)指南

    從零開(kāi)始手寫JDBC連接數(shù)據(jù)庫(kù)的詳細(xì)指南

    在?Java?開(kāi)發(fā)中,數(shù)據(jù)庫(kù)是存儲(chǔ)和管理數(shù)據(jù)的核心組件,JDBC是?Java?程序與數(shù)據(jù)庫(kù)交互的標(biāo)準(zhǔn)?API,本文將帶大家手寫一個(gè)完整的?JDBC?連接數(shù)據(jù)庫(kù)的示例,希望對(duì)大家有所幫助
    2025-07-07

最新評(píng)論

安塞县| 玉山县| 玛纳斯县| 平谷区| 苏尼特右旗| 甘洛县| 开江县| 阿勒泰市| 名山县| 青冈县| 甘洛县| 江西省| 江川县| 巫山县| 东丽区| 易门县| 大宁县| 丹巴县| 镇赉县| 澄迈县| 怀安县| 芦山县| 瑞丽市| 平乡县| 田林县| 福泉市| 都兰县| 启东市| 栖霞市| 海原县| 磐石市| 辽阳县| 淅川县| 嘉鱼县| 平凉市| 锡林浩特市| 湘阴县| 三原县| 江城| 克拉玛依市| 阳高县|