如何实现LangChain4J文档导入Milvus与查询流程分离
问题分析与解决方法
核心问题
你当前使用MilvusContainer启动的是临时Milvus实例,容器停止后所有数据会被销毁。每次运行代码时,新启动的容器都是空状态,移除EmbeddingStoreIngestor.ingest()后自然无法读取之前导入的数据。
解决方案
需要将Milvus改为持久化部署,并将代码拆分为「数据导入」和「查询」两个独立流程,确保两者连接同一个持久化的Milvus实例。
步骤1:部署持久化的Milvus服务
如果用Docker部署,添加数据卷挂载来持久化数据:
docker run -d \ --name milvus-demo \ -p 19530:19530 \ -v $(pwd)/milvus-data:/var/lib/milvus \ milvusdb/milvus:v2.4.5
步骤2:独立的「数据导入」代码
仅需运行一次,将文件导入Milvus:
public class MilvusDataIngestor { public static void main(String[] args) { // 连接到持久化Milvus实例(本地部署地址为localhost:19530) EmbeddingStore<TextSegment> embeddingStore = MilvusEmbeddingStore.builder() .uri("http://localhost:19530") .collectionName("ingest5") .dimension(384) // 需与后续查询代码保持一致 .build(); // 加载并导入文件 List<Document> documents = FileSystemDocumentLoader.loadDocuments("/tmp/t3"); EmbeddingStoreIngestor.ingest(documents, embeddingStore); System.out.println("数据导入完成"); } }
步骤3:独立的「查询」代码
可重复运行,无需再次导入数据:
public class MilvusQueryService { public interface Assistant { String chat(String question); } public static void main(String[] args) { // 连接到同一个持久化Milvus实例 EmbeddingStore<TextSegment> embeddingStore = MilvusEmbeddingStore.builder() .uri("http://localhost:19530") .collectionName("ingest5") .dimension(384) // 必须与导入代码的维度完全一致 .build(); ChatLanguageModel chatModel = OpenAiChatModel.builder() .apiKey("demo") .modelName(GPT_4_O_MINI) .build(); Assistant assistant = AiServices.builder(Assistant.class) .chatLanguageModel(chatModel) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .contentRetriever(EmbeddingStoreContentRetriever.from(embeddingStore)) .build(); String answer = assistant.chat("What is my name?"); System.out.println("answer=" + answer); } }
关键注意事项
- 导入与查询代码的
collectionName、dimension参数必须完全一致,否则无法正确检索数据。 - Milvus服务需保持运行状态,查询时才能连接到存储的向量数据。
- 若需更新数据,可在导入代码中添加增量导入逻辑,无需每次全量导入。
内容的提问来源于stack exchange,提问作者MTilsted
相关产品推荐
相关产品推荐

