LangChain4j(16)——使用milvus进行向量存储

发布于:2025-05-02 ⋅ 阅读:(17) ⋅ 点赞:(0)

非结构化数据(如文本、图像和音频)格式各异,蕴含丰富的潜在语义,因此分析起来极具挑战性。为了处理这种复杂性,Embeddings 被用来将非结构化数据转换成能够捕捉其基本特征的数字向量。然后将这些向量存储在向量数据库中,从而实现快速、可扩展的搜索和分析。

milvus是开源的向量数据库,其提供强大的数据建模功能,使您能够将非结构化或多模式数据组织成结构化的 Collections。它支持多种数据类型,适用于不同的属性模型,包括常见的数字和字符类型、各种向量类型、数组、集合和 JSON,为您节省了维护多个数据库系统的精力。

Milvus 支持各种类型的搜索功能,以满足不同用例的需求:

  • ANN 搜索:查找最接近查询向量的前 K 个向量。
  • 过滤搜索:在指定的过滤条件下执行 ANN 搜索。
  • 范围搜索:查找查询向量指定半径范围内的向量。
  • 混合搜索:基于多个向量场进行 ANN 搜索。
  • 全文搜索:基于 BM25 的全文搜索。
  • Rerankers:根据附加标准或辅助算法调整搜索结果顺序,完善初始 ANN 搜索结果。
  • 获取:根据主键检索数据。
  • 查询使用特定表达式检索数据。

通过docker安装milvus

本文使用docker compose进行安装

version: '3.5'

services:
  etcd:
    container_name: milvus-etcd
    image: quay.io/coreos/etcd:v3.5.5
    environment:
      - ETCD_AUTO_COMPACTION_MODE=revision
      - ETCD_AUTO_COMPACTION_RETENTION=1000
      - ETCD_QUOTA_BACKEND_BYTES=4294967296
      - ETCD_SNAPSHOT_COUNT=50000
    volumes:
      - D:/docker/milvus/etcd:/etcd
    command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd

  minio:
    container_name: milvus-minio
    image: minio/minio:RELEASE.2023-03-20T20-16-18Z
    environment:
      MINIO_ACCESS_KEY: minioadmin
      MINIO_SECRET_KEY: minioadmin
    volumes:
      - D:/docker/milvus/minio:/minio_data
    command: minio server /minio_data
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

  standalone:
    container_name: milvus-standalone
    image: milvusdb/milvus:v2.3.1
    command: ["milvus", "run", "standalone"]
    environment:
      ETCD_ENDPOINTS: etcd:2379
      MINIO_ADDRESS: minio:9000
    volumes:
      - D:/docker/milvus/milvus:/var/lib/milvus
    ports:
      - "19530:19530"
      - "9091:9091"
    depends_on:
      - "etcd"
      - "minio"

networks:
  default:
    name: milvus

通过docker compose,我们需要下载三个镜像:

etcd:用于元存储,存储元数据的快照,如 Collections Schema 和消息消耗检查点

minio:用于存储日志快照文件、标量和向量数据的索引文件以及中间查询结果

milvus:核心服务

安装Attu

Attu是milvus的可视化客户端工具,本例安装windows版Attu。

可通过该地址查看对应版本:GitHub - zilliztech/attu: Web UI for Milvus Vector Database

本例下载并安装v2.3.5版本的Attu。

下载后,双击运行:

设置milvus的连接地址,并连接:

 

向量数据存入milvus

package com.renr.langchain4jnew.app4;

import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.milvus.MilvusEmbeddingStore;

import java.util.List;

public class MilvusEmbeddingStoreTest {

    public static void main(String[] args) {

        // 创建MilvusEmbeddingStore存储对象
        EmbeddingStore<TextSegment> embeddingStore = MilvusEmbeddingStore.builder()
                .uri("http://127.0.0.1:19530") // 连接地址
                .collectionName("test_collection") // 集合名称
                .dimension(384) // 向量维度
                .build();

        // 嵌入模型
        EmbeddingModel embeddingModel = new BgeSmallEnV15QuantizedEmbeddingModel();

        // 将数据向量化并存入milvus
        TextSegment segment1 = TextSegment.from("I like football.");
        Embedding embedding1 = embeddingModel.embed(segment1).content();
        embeddingStore.add(embedding1, segment1);

        TextSegment segment2 = TextSegment.from("The weather is good today.");
        Embedding embedding2 = embeddingModel.embed(segment2).content();
        embeddingStore.add(embedding2, segment2);

        // 搜索
        Embedding queryEmbedding = embeddingModel.embed("What is your favourite sport?").content();
        EmbeddingSearchRequest embeddingSearchRequest = EmbeddingSearchRequest.builder()
                .queryEmbedding(queryEmbedding)
                .maxResults(1)
                .build();
        List<EmbeddingMatch<TextSegment>> matches = embeddingStore.search(embeddingSearchRequest).matches();
        EmbeddingMatch<TextSegment> embeddingMatch = matches.get(0);

        System.out.println(embeddingMatch.score());
        System.out.println(embeddingMatch.embedded().text());
    }
}

运行结果:

查看Attu:


网站公告

今日签到

点亮在社区的每一天
去签到