java實戰-Milvus 2.5.x版本向量庫-通過集合字段變更示例學習相關api demo

文章目錄

  • 前言
    • java實戰-Milvus 2.5.x版本向量庫-通過集合字段變更示例學習相關api demo
      • 1. Milvus版本
      • 2. 示例邏輯分析
      • 3. 集合字段變更示例demo
      • 4. 測試

前言

??如果您覺得有用的話,記得給博主點個贊,評論,收藏一鍵三連啊,寫作不易啊^ _ ^。
??而且聽說點贊的人每天的運氣都不會太差,實在白嫖的話,那歡迎常來啊!!!


java實戰-Milvus 2.5.x版本向量庫-通過集合字段變更示例學習相關api demo

注意:
關于demo中的Milvus 連接池與key的管理參考下面這篇文章。
java-Milvus 向量庫(2.5.x版本)-連接池(多key)與自定義端點監聽設計

1. Milvus版本

在這里插入圖片描述

2. 示例邏輯分析

Milvus 不支持直接修改集合 schema(比如新增字段),所以你只能:

  1. 創建一個新集合(含你想新增的字段);
  2. 把舊集合的數據遷移過去;
  3. 繼續在新集合中做后續操作。

注意的是數據遷移建議用 queryIteratorV2,而不是 searchIteratorV2.

功能queryIteratorV2searchIteratorV2
用途查詢結構化數據(按條件篩選、返回字段)向量搜索,查找相似向量
是否依賴向量字段? 不依賴? 必須提供向量(FloatVector)
用途場景數據導出、分頁查看、遷移、統計等向量相似度匹配(推薦、檢索)
是否支持 filter? 支持 expr / filter? 支持 filter,但只能配合向量使用
返回內容任意字段(非向量也可以)topK 相似度結果(帶 score)

3. 集合字段變更示例demo

package org.example.controller;import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.example.annotation.CommonLog;
import org.example.exception.model.ResponseResult;
import org.example.service.MilvusService;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/**
* @author 楊鎮宇
* @date 2025/7/8 08:46
* @version 1.0
*/
@Api(value = " milvus 練習", tags = {" milvus 練習"})
@Slf4j
@RestController
@RequestMapping(value="api/milvus")
public class MilvusController {@Resourceprivate MilvusService milvusService;@ApiOperation(value = "集合字段變更(數據遷移)測試", notes = "集合字段變更(數據遷移)測試")@CrossOrigin(origins = "*")@CommonLog(methodName = "集合字段變更(數據遷移)測試",className = "MilvusController#updateMigrateData",url = "api/milvus/updateMigrateData")@RequestMapping(value = "/updateMigrateData", method = RequestMethod.POST)public ResponseResult updateMigrateData(){milvusService.updateMigrateData();return ResponseResult.ok("測試完成");}}
package org.example.service.impl;import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.orm.iterator.QueryIterator;
import io.milvus.orm.iterator.SearchIteratorV2;
import io.milvus.response.QueryResultsWrapper;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.ConsistencyLevel;
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.*;
import io.milvus.v2.service.collection.response.DescribeCollectionResp;
import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.request.QueryIteratorReq;
import io.milvus.v2.service.vector.request.SearchIteratorReqV2;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp;
import lombok.extern.slf4j.Slf4j;
import org.example.milvus.config.OldMilvusServiceClient;
import org.example.milvus.model.MilvusAdminClient;
import org.example.milvus.model.MilvusInsertClient;
import org.example.milvus.model.MilvusSearchClient;
import org.example.service.MilvusService;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.*;/**
* @author 楊鎮宇
* @date 2025/7/8 09:02
* @version 1.0
*/
@Slf4j
@Service
public class MilvusServiceImpl implements MilvusService {/*** key:search-module*/@Resourceprivate MilvusSearchClient searchClient;/*** key:insert-module*/@Resourceprivate MilvusInsertClient insertClient;/*** key:admin-module*/@Resourceprivate MilvusAdminClient adminClient;/*** milvusServiceClient舊客戶端*/@Resourceprivate OldMilvusServiceClient oldMilvusServiceClient;// 歸一化函數(單位向量)public  List<Float> normalizeVector(List<Float> vector) {double norm = 0.0;for (Float v : vector) {norm += v * v;}norm = Math.sqrt(norm);List<Float> normalized = new ArrayList<>();for (Float v : vector) {normalized.add((float) (v / norm));}return normalized;}/*** java實戰-Milvus 向量庫 集合字段變更*/@Overridepublic void updateMigrateData() {MilvusClientV2 client = adminClient.getClient();int dim = 4;// 維度String collectionName = "java_test";String description = "測試表";CreateCollectionReq.CollectionSchema collectionSchema = client.createSchema();collectionSchema.addField(AddFieldReq.builder().fieldName("id").dataType(DataType.Int64).isPrimaryKey(Boolean.TRUE).autoID(Boolean.FALSE).description("id").build());collectionSchema.addField(AddFieldReq.builder().fieldName("vector").dataType(DataType.FloatVector).dimension(dim).description("向量字段").build());collectionSchema.addField(AddFieldReq.builder().fieldName("user").dataType(DataType.VarChar).maxLength(100).description("用戶").build());collectionSchema.addField(AddFieldReq.builder().fieldName("timestamp").dataType(DataType.Int64).description("時間").build());log.info("=============創建測試表提供測試===================");createTable(dim,collectionSchema,client,collectionName,description);log.info("--------------插入1200條數據用作測試--------------");MilvusClientV2 insert = insertClient.getClient();batchInsert(insert,collectionName);log.info("--------------查詢前10條數據驗證--------------");List<Float> queryVector = Arrays.asList(1.0f, 2.0f, 3.0f, 4.0f); // 示例向量query(client,queryVector,collectionName);// 新增字段AddFieldReq addBuild = AddFieldReq.builder().fieldName("age").dataType(DataType.VarChar).maxLength(100).description("年齡").isNullable(true)   // ? 允許為空.build();collectionSchema.addField(addBuild);log.info("=============創建新表,進行數據遷移===================");String newCollection = migrateData(client, collectionName, collectionSchema, dim, description);log.info("--------------查詢前10條數據驗證--------------");query(client,queryVector,newCollection);log.info("刪除舊表");DropCollectionReq dropCollectionReq = DropCollectionReq.builder().collectionName(collectionName).build();client.dropCollection(dropCollectionReq);}public void query(MilvusClientV2 client,List<Float> queryVector,String collectionName){queryVector = normalizeVector(queryVector); // ? 添加歸一化SearchIteratorReqV2 searchReq = SearchIteratorReqV2.builder().collectionName(collectionName)              // 替換為你的集合名.outputFields(Arrays.asList("id", "user", "timestamp","vector")) // 可加你想驗證的字段.batchSize(10L).vectorFieldName("vector").vectors(Collections.singletonList(new FloatVec(queryVector))).filter("id > 0")  // 可選條件,確保有返回.topK(10)          // 查詢前 10 個最相似的.metricType(IndexParam.MetricType.COSINE).consistencyLevel(ConsistencyLevel.BOUNDED).build();SearchIteratorV2 searchIterator = client.searchIteratorV2(searchReq);log.info("🔍 表【{}】:前 10 條查詢結果:",collectionName);while (true) {List<SearchResp.SearchResult> res = searchIterator.next();if (res.isEmpty()) {log.info("🔍 查詢結束");searchIterator.close();break;}for (SearchResp.SearchResult record : res) {Map<String, Object> entity = record.getEntity();log.info("🔍 >>>>> id:{},user:{},timestamp:{},vector:{}",entity.get("id"),entity.get("user"),entity.get("timestamp"),entity.get("vector"));}}}/*** 插入1200條數據* @param client*/public void batchInsert(MilvusClientV2 client,String collectionName){Gson gson = new Gson();List<JsonObject> dataList = new ArrayList<>();for (long i = 1; i <= 1200; i++) {JsonObject row = new JsonObject();// 構造向量:這里用隨機值或自定義值填充List<Float> vector = Arrays.asList(1.0f * i, 2.0f * i, 3.0f * i, 4.0f * i);  // dim = 4row.add("vector", gson.toJsonTree(normalizeVector(vector)));row.addProperty("id", i);                    // 手動指定主鍵row.addProperty("user", "user_" + i);        // 示例字段row.addProperty("timestamp", System.currentTimeMillis());     // 注意 Int16 用 shortdataList.add(row);// 每 200 條插入一次,避免過大 payloadif (dataList.size() == 200 || i == 1200) {InsertReq insertReq = InsertReq.builder().collectionName(collectionName)  // 替換為你的集合名.data(dataList).build();client.insert(insertReq);log.info("? 已插入 {} 條數據", i);dataList.clear();}}}/*** 新增字段,數據遷移*/public String migrateData(MilvusClientV2 client, String collectionName,CreateCollectionReq.CollectionSchema collectionSchema,int dim,String description){String newCollection = collectionName + "_new";// 獲取舊集合結構信息DescribeCollectionResp oldSchemaResp = client.describeCollection(DescribeCollectionReq.builder().collectionName(collectionName).build());List<String> oldFieldNames = oldSchemaResp.getFieldNames();// 創建新集合createTable(dim,collectionSchema,client,newCollection,description);// 獲取新集合結構信息DescribeCollectionResp newSchemaResp = client.describeCollection(DescribeCollectionReq.builder().collectionName(newCollection).build());List<String> newFieldNames = newSchemaResp.getFieldNames();Set<String> oldFieldSet = new HashSet<>(oldFieldNames);Gson gson = new Gson();  // 如果沒有引入 gson,請確保引入:com.google.code.gson:gsonlong offset = 0;long limit = 200;while (true) {QueryIteratorReq queryReq = QueryIteratorReq.builder().collectionName(collectionName).expr("id > 0").outputFields(oldFieldNames).batchSize(limit).offset(offset).limit(limit).consistencyLevel(ConsistencyLevel.BOUNDED).build();QueryIterator queryIterator = client.queryIterator(queryReq);List<QueryResultsWrapper.RowRecord> rows = queryIterator.next();queryIterator.close();if (rows.isEmpty()) {log.info("? 數據遷移完成,總記錄數: {}", offset);break;}List<JsonObject> insertRows = new ArrayList<>();for (QueryResultsWrapper.RowRecord row : rows) {JsonObject json = new JsonObject();for (String field : newFieldNames) {if (oldFieldSet.contains(field)) {Object value = row.get(field);if (value instanceof Number) {json.addProperty(field, (Number) value);} else if (value instanceof String) {json.addProperty(field, (String) value);} else if (value instanceof List<?>) {json.add(field, gson.toJsonTree(value));} else {log.warn("? 未處理的字段類型: {} -> {}", field, value);}} else {// 🔧 新增字段統一設置為 null 或默認值json.addProperty(field, "");}}insertRows.add(json);}InsertReq insertReq = InsertReq.builder().collectionName(newCollection).data(insertRows).build();client.insert(insertReq);log.info("? 插入第 {} ~ {} 條數據", offset + 1, offset + rows.size());offset += rows.size();}log.info("? 集合 `{}` 遷移完成", newCollection);return newCollection;}/*** 創建集合 + 為所有向量字段建索引*/public static void createTable(int dim,CreateCollectionReq.CollectionSchema collectionSchema,MilvusClientV2 client, String collectionName,  String description) {// 先判斷是否存在,存在先刪除HasCollectionReq name = HasCollectionReq.builder().collectionName(collectionName).build();if (client.hasCollection(name)) {log.info("Collection `{}` 已存在,準備刪除", collectionName);client.dropCollection(DropCollectionReq.builder().collectionName(collectionName)// 集合名稱.timeout(60000L)//進程的超時時長。指定時長到期后,進程將終止, 默認為60000L.build());log.info("Collection `{}` 刪除成功", collectionName);}IndexParam indexParam = IndexParam.builder().fieldName("vector").metricType(IndexParam.MetricType.COSINE) // 檢索時計算向量之間的相似度方式使用 COSINE(余弦相似度),COSINE 適用于歸一化向量的相似度匹配,等價于夾角越小越相似。.build();// 創建 CollectionSchema 和 CollectionCreateCollectionReq createCollectionReq = CreateCollectionReq.builder().collectionSchema(collectionSchema) // 留空表示此集合將使用默認設置創建。要設置具有自定義架構的集合,您需要創建一個CollectionSchema對象并在此處引用它。.autoID(false)// 當數據插入到該集合時,主字段是否自動遞增 ,TRUE自動遞增.collectionName(collectionName)//表名.description(description)//描述.dimension(dim) // 保存向量嵌入的集合字段的維數.metricType("COSINE")//此集合使用的算法用于測量向量嵌入之間的相似性。   該值默認為IP。可能的值為L2、IP和COSINE。有關這些指標類型的詳細信息.indexParams(Collections.singletonList(indexParam)).build();// 創建集合client.createCollection(createCollectionReq);log.info("Collection `{}` 創建完成", collectionName);DescribeCollectionResp resp = client.describeCollection(DescribeCollectionReq.builder().collectionName(collectionName).build());List<CreateCollectionReq.FieldSchema> fieldSchemaList = resp.getCollectionSchema().getFieldSchemaList();log.info("-------------------------【{}】集合結構-----------------------",collectionName);for (CreateCollectionReq.FieldSchema fieldSchema:fieldSchemaList){String field = fieldSchema.getName();String fieldDescription = fieldSchema.getDescription();DataType dataType = fieldSchema.getDataType();log.info("字段名:{},類型:{},備注:{}",field,dataType,fieldDescription);}}}

4. 測試

測試執行:
在這里插入圖片描述
效果:
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/88193.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/88193.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/88193.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HashMap的get與put流程源碼深度解析

目錄 一、HashMap基礎結構 二、put操作流程分析 put操作關鍵步驟總結 三、get操作流程分析 get操作關鍵步驟總結 四、延伸 1.hash()方法 2. 擴容 resize()方法的主要邏輯&#xff1a; Java 8中對擴容的優化&#xff1a; 3. 轉向紅黑樹的條件 HashMap作為Java集合框架…

初識Neo4j之圖數據庫(二)

目錄 一、圖數據庫如何工作 二、為什么使用圖數據庫 Neo4j 圖數據庫以節點、關系和屬性的形式存儲數據&#xff0c;而不是用表或文檔進行數據存儲。這意味著用戶可以像在白板上畫草圖那樣來組織數據。而且&#xff0c;由于圖數據庫不受限于預先定義的數據模型&#xff0c;因此…

Python 中 ffmpeg-python 庫的詳細使用

文章目錄 一、ffmpeg-python庫概述1.1 ffmpeg-python庫介紹1.2 安裝1.3 優勢1.4 常用場景二、基本使用2.1 視頻信息獲取2.2 視頻轉碼三、視頻處理3.1 視頻裁剪3.2 視頻縮放3.3 視頻旋轉四、音頻處理4.1 提取音頻4.2 音頻混合五、高級使用5.1 添加水印5.2 視頻濾鏡5.3 視頻合成5…

JAVA策略模式demo【設計模式系列】

策略模式用在統一的入口&#xff0c;但需要根據某個類型判斷后續執行邏輯&#xff0c;例如我最近遇到的場景&#xff1a;我需要對接一個設備&#xff0c;前端請求我這邊&#xff0c;我再去和設備交互&#xff0c;但設備種類很多&#xff0c;各自有自己的接入規則&#xff01;傳…

mysql索引:索引應該選擇哪種數據結構 B+樹 MySQL中的頁 頁主體 頁目錄 索引分類

索引是什么?為什么要使用索引? 以前學數據結構時學了ArrayList,我們可以往里面存放數據 但是有問題,也就是說當程序重啟或是電腦關機之后,數據就沒有了,為什么? 因為他的數據是保存在內存中的 數據庫把數據保存在磁盤中,就可以完成對數據的持久化內存與外存的區別 內存&…

SpringBoot靜態資源與緩存配置全解析

springboot中靜態資源classpath就是resource文件夾下歡迎頁規則項目啟動默認去找靜態資源下的index.html頁面 默認訪問該頁面favicon原則在靜態資源目錄下尋找favicon.ico緩存實驗在請求中使用Cache-Control 時&#xff0c;它可選的值有&#xff1a;在響應中使用Cache-Control …

基于 Python Django 和 Spark 的電力能耗數據分析系統設計與實現7000字論文實現

摘要隨著能源問題日益突出&#xff0c;電力能耗數據分析對于提高能源利用效率、降低能源消耗具有重要意義。本文設計并實現了一個基于 Python Django 和 Spark 的電力能耗數據分析系統。系統采用前后端分離架構&#xff0c;前端使用 Django 框架實現用戶界面&#xff0c;后端使…

elementUI vue2 前端表格table數據導出(二)

為啥前端導出不在贅述了&#xff0c;不然讀者也難看到這篇文章。第一步&#xff1a;安裝依賴npm install vue-json-excel第二步&#xff1a;引用依賴配置// 導出Excel文件組件 import JsonExcel from vue-json-excel; Vue.component(downloadExcel, JsonExcel)第三步&#xff1…

RabbitMQ 4.1.1-Local random exchange體驗

Local Random Exchange 一種 RabbitMQ 4.0 引入的新型交換機&#xff0c;主要是為 request-reply&#xff08;RPC&#xff09;場景 設計的。 使用這種交換機時&#xff0c;消息只會被路由到本地節點上的隊列&#xff0c;可以確保極低的消息發布延遲。如果有多個本地隊列綁定到該…

中山排氣歧管批量自動化智能化3D尺寸測量及cav檢測分析

當前制造業快速發展&#xff0c;傳統測量方法正面臨嚴峻挑戰。生產規模的持續擴張使得現有測量手段逐漸暴露出效率不足的問題&#xff0c;這種技術滯后性正在直接影響企業的整體生產效率。具體表現為測量速度跟不上生產節拍&#xff0c;精度要求難以達標&#xff0c;最終導致生…

Debian 11 Bullseye 在線安裝docker

首先移除所有錯誤的 Docker 軟件源&#xff1a;sudo rm -f /etc/apt/sources.list.d/docker*安裝必要依賴sudo apt update sudo apt install -y ca-certificates curl gnupg添加 Docker 官方 GPG 密鑰&#xff08;使用國內鏡像&#xff09;&#xff1a;curl -fsSL https://mirr…

Spring Boot 項目中多數據源配置使用場景

在 Spring Boot 中配置多數據源是一個非常常見的需求&#xff0c;主要用于以下場景&#xff1a; 讀寫分離&#xff1a;一個主數據庫&#xff08;Master&#xff09;負責寫操作&#xff0c;一個或多個從數據庫&#xff08;Slave&#xff09;負責讀操作&#xff0c;以提高性能和可…

FAAC 在海思平臺使用得到aac實時音頻流

FAAC 在海思平臺使用得到aac實時音頻流 使用 FAAC將音頻 pcm轉為 aac 主要參見這篇博客 FAAC 在君正平臺使用得到aac實時音頻流_君正 x2600 音頻-CSDN博客

javascript函數參數類似python函數參數星號*解耦數組

序言通常情況下&#xff0c;我們很可能不清楚參數有多少&#xff0c;這個時候用的都是數組。但是使用數組和單個元素&#xff0c;從內心情感來說&#xff0c;它們是兩種維度&#xff0c;為了讓參數成為一個數組&#xff0c;把單個輸入的參數強加一個數組的外殼&#xff0c;并不…

C語言基礎(1)

1.編譯器的選擇 我們的c語言是一門&#xff0c;我們寫的c語言代碼是文本文件(存放在.c為后綴的文件中)&#xff0c;文本文件本身無法被執行&#xff0c;必須通過編譯器的編譯和鏈接器的鏈接&#xff0c;生成可執行的二進制文件&#xff0c;才能夠被執行注意&#xff1a; 每個源…

Rust賦能美團云原生DevOps實踐

Rust 云原生 DevOps 實踐 在云原生環境中,Rust 的高性能與安全性使其成為構建微服務和基礎設施工具的理想選擇。Docker 作為容器化標準工具,結合 Rust 的跨平臺特性,可高效實現持續集成與部署(CI/CD)。 構建優化的 Rust Docker 鏡像 多階段構建是 Rust 項目容器化的關鍵…

計算機網絡實驗——配置ACL

ACL基礎一、實驗目的1. 配置H3C路由器基本ACL。二、實驗要求1. 熟練掌握網絡配置能力。2. 熟練掌握ACL基本配置。三、實驗步驟&#xff08;1&#xff09;使用reset saved-configuration命令和reboot命令&#xff0c;重置路由器原有配置&#xff0c;如圖1所示。圖 1&#xff08;…

在本地部署mcp服務器實現自然語言操作mysql數據庫,輕松實現數據表的增~ 刪~ 改~ 查~

1.將寫好的mcp_server代碼放在本地任意盤&#xff01; import asyncio import logging import os import sys from mysql.connector import connect, Error from mcp.server import Server from mcp.types import Resource, Tool, TextContent from pydantic import AnyUrl# Co…

2025快手創作者中心發布視頻python實現

難度還行&#xff0c;只有一個__NS_sig3加密&#xff0c;流程麻煩點cookies_list cookie.split("; ")cookie_dict {}# 遍歷每個 Cookie&#xff0c;根據等號將鍵值對拆分并添加到字典中for cookie in cookies_list:key_value cookie.split("")if len(ke…

Android 組件內核

文章目錄什么是binder1. 什么是Binder&#xff1f;2. Binder架構組成3. 工作原理與通信流程1&#xff09;服務注冊2&#xff09;服務查詢3&#xff09;通信過程4&#xff09;核心數據結構4. 關鍵技術點5. 常見面試考點1&#xff09;Binder與傳統IPC&#xff08;Socket、管道、共…