Milvus Java 快速入门

这是最简、可直接运行的 Java 版 Milvus 入门教程,适配 Milvus 2.4+,包含:连接、建集合、建索引、插入数据、向量检索全套流程。

一、环境准备

  1. 先启动 Milvus 服务(推荐 Docker 单机版)

    bash 复制代码
    wget https://github.com/milvus-io/milvus/releases/download/v2.4.10/milvus-standalone-docker-compose.yml -O docker-compose.yml
    docker-compose up -d
  2. Java 环境:JDK 21

  3. Maven 引入依赖

二、Maven 依赖

直接复制到 pom.xml

xml 复制代码
<dependencies>
    <!-- Milvus Java SDK -->
    <dependency>
        <groupId>io.milvus</groupId>
        <artifactId>milvus-sdk-java</artifactId>
        <version>2.4.10</version>
    </dependency>
    <!-- 工具类 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>2.0.32</version>
    </dependency>
</dependencies>

三、完整可运行代码

核心流程

  1. 连接 Milvus
  2. 创建集合(表)
  3. 创建索引(必须建索引才能检索)
  4. 插入向量数据
  5. 加载集合到内存
  6. 向量相似检索
java 复制代码
import io.milvus.client.MilvusClient;
import io.milvus.client.MilvusServiceClient;
import io.milvus.common.clientenum.ConsistencyLevelEnum;
import io.milvus.grpc.DataType;
import io.milvus.grpc.SearchResults;
import io.milvus.param.ConnectParam;
import io.milvus.param.IndexType;
import io.milvus.param.MetricType;
import io.milvus.param.collection.*;
import io.milvus.param.dml.InsertParam;
import io.milvus.param.dml.SearchParam;
import io.milvus.param.index.CreateIndexParam;
import io.milvus.response.SearchResultsWrapper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class MilvusJavaQuickStart {
    // 配置
    private static final String HOST = "localhost";
    private static final int PORT = 19530;
    private static final String COLLECTION_NAME = "java_demo_collection";
    private static final int VECTOR_DIM = 128; // 向量维度

    public static void main(String[] args) {
        // 1. 连接 Milvus
        MilvusClient client = new MilvusServiceClient(
            ConnectParam.newBuilder()
                .withHost(HOST)
                .withPort(PORT)
                .build()
        );
        System.out.println("✅ Milvus 连接成功");

        try {
            // 2. 创建集合
            createCollection(client);

            // 3. 创建索引
            createIndex(client);

            // 4. 插入数据
            insertData(client);

            // 5. 加载集合到内存(检索前必须执行)
            loadCollection(client);

            // 6. 向量检索
            searchVector(client);

            System.out.println("\n🎉 全部执行完成!");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    // 创建集合(表)
    private static void createCollection(MilvusClient client) {
        // 先判断是否存在,存在则删除
        HasCollectionParam hasCollectionParam = HasCollectionParam.newBuilder()
                .withCollectionName(COLLECTION_NAME)
                .build();
        if (client.hasCollection(hasCollectionParam).getData()) {
            DropCollectionParam dropParam = DropCollectionParam.newBuilder()
                    .withCollectionName(COLLECTION_NAME)
                    .build();
            client.dropCollection(dropParam);
        }

        // 定义字段:ID + 向量 + 文本
        List<FieldType> fields = new ArrayList<>();
        // 主键ID
        fields.add(FieldType.newBuilder()
                .withName("id")
                .withDataType(DataType.Int64)
                .withPrimaryKey(true)
                .withAutoID(true) // 自动生成ID
                .build());
        // 向量字段
        fields.add(FieldType.newBuilder()
                .withName("embedding")
                .withDataType(DataType.FloatVector)
                .withDimension(VECTOR_DIM)
                .build());
        // 文本元数据
        fields.add(FieldType.newBuilder()
                .withName("text")
                .withDataType(DataType.VarChar)
                .withMaxLength(64)
                .build());

        // 创建集合
        CreateCollectionParam createParam = CreateCollectionParam.newBuilder()
                .withCollectionName(COLLECTION_NAME)
                .withFieldTypes(fields)
                .withConsistencyLevel(ConsistencyLevelEnum.STRONG)
                .build();
        client.createCollection(createParam);
        System.out.println("✅ 集合创建成功");
    }

    // 创建索引(必须建索引才能检索)
    private static void createIndex(MilvusClient client) {
        CreateIndexParam indexParam = CreateIndexParam.newBuilder()
                .withCollectionName(COLLECTION_NAME)
                .withFieldName("embedding")
                .withIndexType(IndexType.HNSW) // 索引类型:HNSW(高性能)
                .withMetricType(MetricType.L2) // 距离算法:欧氏距离
                .withExtraParam("{\"M\":16,\"efConstruction\":200}")
                .build();
        client.createIndex(indexParam);
        System.out.println("✅ 索引创建成功");
    }

    // 插入测试数据
    private static void insertData(MilvusClient client) {
        List<InsertParam.Field> fields = new ArrayList<>();

        // 生成 10 条随机向量 + 文本 
        List<List<Float>> vectors = new ArrayList<>();
        List<String> texts = new ArrayList<>();
        Random random = new Random();

        for (int i = 0; i < 10; i++) {
            // 生成 128 维随机向量
            List<Float> vec = new ArrayList<>();
            for (int j = 0; j < VECTOR_DIM; j++) {
                vec.add(random.nextFloat());
            }
            vectors.add(vec);
            texts.add("Java测试文本_" + i);
        }

        fields.add(new InsertParam.Field("embedding", vectors));
        fields.add(new InsertParam.Field("text", texts));

        // 插入
        InsertParam insertParam = InsertParam.newBuilder()
                .withCollectionName(COLLECTION_NAME)
                .withFields(fields)
                .build();
        client.insert(insertParam);
        System.out.println("✅ 数据插入成功:10 条");
    }

    // 加载集合(检索前必须执行)
    private static void loadCollection(MilvusClient client) {
        LoadCollectionParam loadParam = LoadCollectionParam.newBuilder()
                .withCollectionName(COLLECTION_NAME)
                .build();
        client.loadCollection(loadParam);
        // 等待加载完成
        try { Thread.sleep(1000); } catch (InterruptedException e) {}
        System.out.println("✅ 集合已加载到内存");
    }

    // 向量相似检索
    private static void searchVector(MilvusClient client) throws Exception {
        // 生成随机查询向量
        List<Float> queryVector = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < VECTOR_DIM; i++) {
            queryVector.add(random.nextFloat());
        }

        // 检索参数
        SearchParam searchParam = SearchParam.newBuilder()
                .withCollectionName(COLLECTION_NAME)
                .withMetricType(MetricType.L2)
                .withTopK(3) // 返回最相似的 3 条
                .withVectors(Arrays.asList(queryVector))
                .withVectorFieldName("embedding")
                .withOutFields(Arrays.asList("text")) // 返回文本字段
                .withParams("{\"ef\":50}")
                .build();

        // 执行检索
        SearchResults response = client.search(searchParam);
        SearchResultsWrapper wrapper = new SearchResultsWrapper(response.getResults());

        System.out.println("\n🔍 检索结果(Top3):");
        List<SearchResultsWrapper.IDScore> scores = wrapper.getIDScore(0);
        for (SearchResultsWrapper.IDScore score : scores) {
            System.out.println("ID:" + score.getLongID()
                    + " | 相似度距离:" + String.format("%.4f", score.getScore())
                    + " | 文本:" + score.getFieldValue("text"));
        }
    }
}

四、运行说明

  1. 确保 Milvus 服务正常运行
  2. 直接运行 main 方法
  3. 控制台输出:连接成功 → 建集合 → 建索引 → 插入数据 → 检索结果

五、核心概念速查

概念 说明
集合(Collection) 相当于数据库的
字段(Field) 表的列,支持向量/数字/字符串
索引(Index) 向量必须建索引才能快速检索
HNSW 最常用索引类型,查询速度快、耗内存
L2 欧氏距离,最通用的向量相似度算法
加载集合 检索前必须加载到内存

六、常用扩展

  1. 真实向量:把随机向量替换成文本嵌入模型(如 Sentence-BERT)输出的向量
  2. 过滤检索 :增加 withExpr("text like '%Java%'") 实现条件检索
  3. 删除数据 :使用 DeleteParam 按 ID/条件删除
  4. 可视化工具 :Attu(docker run -p 8000:3000 zilliz/attu

总结

  1. 这套代码是 Java 操作 Milvus 最简标准模板,可直接用于项目
  2. 必须流程:建集合 → 建索引 → 插入 → 加载 → 检索
相关推荐
leiming62 小时前
巧用 FreeRTOS 任务通知作“邮箱”:NeoPixel 灯环控制实战
java·前端·算法
东离与糖宝2 小时前
Java 26 FFM API进阶:零JNI调用TensorRT/OpenVINO,AI端到端延迟砍半
java·人工智能
红云梦2 小时前
互联网三高-高性能之线程池与连接池调优
java·线程池·连接池·池化技术
瑶山2 小时前
SpringBoot + MongoDB 5分钟快速集成:从0到1实操指南
java·数据库·spring boot·后端·mongodb
迈巴赫车主2 小时前
蓝桥杯192.等差数列java
java·数据结构·算法·职场和发展·蓝桥杯
JOEH602 小时前
为什么你的接口总是响应慢?Java 生产环境 6 大排查误区
java
linux修理工2 小时前
Claude API 密钥更换方法
java·数据库·mysql
clamlss2 小时前
💥 踩坑实录:MapStruct 映射失效?揭秘 Lombok 组合下的编译期陷阱
java·后端
殷紫川2 小时前
CAS 无锁并发深度解析:从 CPU 原语、JDK 源码到生产实战与避坑指南
java