You need to sign in before continuing.

Commit 8cb723cdcaa669d899bf92d53e822bfe937f8e3b

Authored by qianbao
1 parent d72de0c4

添加向量库

src/main/java/com/xly/milvus/service/impl/MilvusServiceImpl.java
... ... @@ -337,30 +337,122 @@ public class MilvusServiceImpl implements MilvusService {
337 337 }
338 338  
339 339 @Override
340   - public List<Map<String, Object>> getDataToCollection(String collectionName, String milvusFilter,String searchText,Integer size,List<String> fields,String vectorValue,String sceneName){
341   - log.info("开始相似度查询: collection={}, searchText={}", collectionName, searchText);
342   - // 2. 设置范围搜索参数
343   - Map<String, Object> searchParams = new HashMap<>();
344   - searchParams.put("nprobe", 10);
345   - // 对于 IP 度量,相似度范围在 [minScore, maxScore]
346   - searchParams.put("radius", 0.9); // 最小相似度
347   - searchParams.put("range_filter", 1); // 最大相似度
348   - if(ObjectUtil.isEmpty(fields)){
  340 + public List<Map<String, Object>> getDataToCollection(String collectionName,
  341 + String milvusFilter,
  342 + String searchText,
  343 + Integer size,
  344 + List<String> fields,
  345 + String vectorValue,
  346 + String sceneName) {
  347 + log.info("开始查询: collection={}, searchText={}, vectorValue={}", collectionName, searchText, vectorValue);
  348 +
  349 + // 设置输出字段
  350 + if (ObjectUtil.isEmpty(fields)) {
349 351 fields = new ArrayList<>();
350 352 }
351 353 fields.add("sSlaveId");
352 354 fields.add("metadata");
353   - // 1. 构建查询(通用)
  355 +
  356 + // 根据 vectorValue 判断走哪个查询
  357 + if (ObjectUtil.isNotEmpty(vectorValue)) {
  358 + // vectorValue 不为空:走向量相似度搜索(使用 SearchReq)
  359 + log.info("使用向量相似度搜索,vectorValue 存在");
  360 + return similaritySearchWithVector(collectionName, milvusFilter, size, fields, vectorValue);
  361 +// } else if (ObjectUtil.isNotEmpty(searchText)) {
  362 +// // vectorValue 为空但 searchText 不为空:走文本向量化搜索(使用 SearchReq)
  363 +// log.info("使用文本向量化搜索,searchText={}", searchText);
  364 +// return similaritySearchWithText(collectionName, milvusFilter, searchText, size, fields);
  365 + } else {
  366 + // vectorValue 和 searchText 都为空:走全量数据查询(使用 QueryReq)
  367 + log.info("使用全量数据查询,无搜索条件");
  368 + return queryAllData(collectionName, milvusFilter, fields,size);
  369 + }
  370 + }
  371 +
  372 + /**
  373 + * 全量数据查询(使用 Query API)
  374 + */
  375 + private List<Map<String, Object>> queryAllData(String collectionName,
  376 + String milvusFilter,
  377 + List<String> fields,
  378 + Integer size) {
  379 + // 使用 QueryReqBuilder(不需要向量数据)
  380 + QueryReq.QueryReqBuilder builder = QueryReq.builder()
  381 + .collectionName(collectionName)
  382 + .outputFields(fields);
  383 + if (ObjectUtil.isNotEmpty(milvusFilter)) {
  384 + builder.filter(milvusFilter);
  385 + }
  386 + // 可选:如果 size 有值,可以设置 limit
  387 + if (ObjectUtil.isNotEmpty(size)) {
  388 + builder.limit(size);
  389 + }
  390 + QueryReq queryReq = builder.build();
  391 + QueryResp queryResp = milvusClient.query(queryReq);
  392 + return processMilvusResults(queryResp);
  393 + }
  394 +
  395 + /**
  396 + * 使用文本向量化进行相似度搜索
  397 + */
  398 + private List<Map<String, Object>> similaritySearchWithText(String collectionName,
  399 + String milvusFilter,
  400 + String searchText,
  401 + Integer size,
  402 + List<String> fields) {
  403 + // 向量化搜索文本
  404 + List<Float> vectorList = vectorizationService.textToVector(searchText);
  405 + if (vectorList == null || vectorList.isEmpty()) {
  406 + throw new RuntimeException("向量化失败");
  407 + }
  408 +
  409 + // 转换为 float[]
  410 + float[] floatArray = new float[vectorList.size()];
  411 + for (int i = 0; i < vectorList.size(); i++) {
  412 + floatArray[i] = vectorList.get(i);
  413 + }
  414 +
  415 + // 设置搜索参数
  416 + Map<String, Object> searchParams = new HashMap<>();
  417 + searchParams.put("nprobe", 10);
  418 + searchParams.put("radius", 0.9);
  419 + searchParams.put("range_filter", 1);
  420 +
  421 + // 构建搜索请求
  422 + FloatVec floatVec = new FloatVec(floatArray);
354 423 SearchReq.SearchReqBuilder builder = SearchReq.builder()
355 424 .collectionName(collectionName)
356 425 .topK(size)
357 426 .metricType(IndexParam.MetricType.IP)
358 427 .outputFields(fields)
359   -// .filterType(FilterType.POST_FILTER)
360   - .searchParams(searchParams);
361   - if(ObjectUtil.isEmpty(vectorValue)){
362   - vectorValue = sceneName;
  428 + .searchParams(searchParams)
  429 + .data(Collections.singletonList(floatVec))
  430 + .annsField("vector");
  431 +
  432 + if (ObjectUtil.isNotEmpty(milvusFilter)) {
  433 + builder.filter(milvusFilter);
363 434 }
  435 +
  436 + SearchReq searchReq = builder.build();
  437 + SearchResp searchResp = milvusClient.search(searchReq);
  438 +
  439 + return processMilvusResults(searchResp);
  440 + }
  441 +
  442 + /**
  443 + * 使用已有向量进行相似度搜索
  444 + */
  445 + private List<Map<String, Object>> similaritySearchWithVector(String collectionName,
  446 + String milvusFilter,
  447 + Integer size,
  448 + List<String> fields,
  449 + String vectorValue) {
  450 + // 设置搜索参数
  451 + Map<String, Object> searchParams = new HashMap<>();
  452 + searchParams.put("nprobe", 10);
  453 + searchParams.put("radius", 0.9);
  454 + searchParams.put("range_filter", 1);
  455 + // 解析向量字符串为 float 数组
364 456 // 1. 向量化搜索文本
365 457 List<Float> vectorList = vectorizationService.textToVector(vectorValue);
366 458 if (vectorList == null || vectorList.isEmpty()) {
... ... @@ -373,31 +465,72 @@ public class MilvusServiceImpl implements MilvusService {
373 465 }
374 466 // 3. 创建 Milvus FloatVec 对象
375 467 FloatVec floatVec = new FloatVec(floatArray);
376   - builder.data(Collections.singletonList(floatVec))
377   - .annsField("vector"); // 向量字段名
  468 + SearchReq.SearchReqBuilder builder = SearchReq.builder()
  469 + .collectionName(collectionName)
  470 + .topK(size)
  471 + .metricType(IndexParam.MetricType.IP)
  472 + .outputFields(fields)
  473 + .searchParams(searchParams)
  474 + .data(Collections.singletonList(floatVec))
  475 + .annsField("vector");
378 476  
379   - if(ObjectUtil.isNotEmpty(milvusFilter)){
  477 + if (ObjectUtil.isNotEmpty(milvusFilter)) {
380 478 builder.filter(milvusFilter);
381 479 }
382   - // 4. 构建搜索请求
383   -// SearchReq searchReq = SearchReq.builder()
384   -// .collectionName(collectionName)
385   -// .data(Collections.singletonList(floatVec))
386   -// .annsField("vector") // 向量字段名
387   -// .topK(size) // 返回最相似的10条
388   -// .metricType(IndexParam.MetricType.IP) // 内积相似度
389   -// .outputFields(fields)
390   -// .searchParams(searchParams)
391   -// .filter(milvusFilter)
392   -// .build();
393   - // 5. 执行搜索
  480 +
394 481 SearchReq searchReq = builder.build();
395 482 SearchResp searchResp = milvusClient.search(searchReq);
396   -
397   - // 6. 处理结果
398 483 return processMilvusResults(searchResp);
399 484 }
400 485  
  486 +// public List<Map<String, Object>> getDataToCollection(String collectionName, String milvusFilter,String searchText,Integer size,List<String> fields,String vectorValue,String sceneName){
  487 +// log.info("开始相似度查询: collection={}, searchText={}", collectionName, searchText);
  488 +// // 2. 设置范围搜索参数
  489 +// Map<String, Object> searchParams = new HashMap<>();
  490 +// searchParams.put("nprobe", 10);
  491 +// // 对于 IP 度量,相似度范围在 [minScore, maxScore]
  492 +// searchParams.put("radius", 0.9); // 最小相似度
  493 +// searchParams.put("range_filter", 1); // 最大相似度
  494 +// if(ObjectUtil.isEmpty(fields)){
  495 +// fields = new ArrayList<>();
  496 +// }
  497 +// fields.add("sSlaveId");
  498 +// fields.add("metadata");
  499 +// // 1. 构建查询(通用)
  500 +// SearchReq.SearchReqBuilder builder = SearchReq.builder()
  501 +// .collectionName(collectionName)
  502 +// .topK(size)
  503 +// .metricType(IndexParam.MetricType.IP)
  504 +// .outputFields(fields)
  505 +//// .filterType(FilterType.POST_FILTER)
  506 +// .searchParams(searchParams);
  507 +// if(ObjectUtil.isNotEmpty(vectorValue)){
  508 +// // 1. 向量化搜索文本
  509 +// List<Float> vectorList = vectorizationService.textToVector(vectorValue);
  510 +// if (vectorList == null || vectorList.isEmpty()) {
  511 +// throw new RuntimeException("向量化失败");
  512 +// }
  513 +// // 2. 转换为 float[]
  514 +// float[] floatArray = new float[vectorList.size()];
  515 +// for (int i = 0; i < vectorList.size(); i++) {
  516 +// floatArray[i] = vectorList.get(i);
  517 +// }
  518 +// // 3. 创建 Milvus FloatVec 对象
  519 +// FloatVec floatVec = new FloatVec(floatArray);
  520 +// builder.data(Collections.singletonList(floatVec))
  521 +// .annsField("vector"); // 向量字段名
  522 +// }
  523 +// if(ObjectUtil.isNotEmpty(milvusFilter)){
  524 +// builder.filter(milvusFilter);
  525 +// }
  526 +// // 5. 执行搜索
  527 +// SearchReq searchReq = builder.build();
  528 +// SearchResp searchResp = milvusClient.search(searchReq);
  529 +//
  530 +// // 6. 处理结果
  531 +// return processMilvusResults(searchResp);
  532 +// }
  533 +
401 534  
402 535 /**
403 536 * 判断 Milvus 过滤条件是否有效(支持 TEXT_MATCH 全文检索)
... ... @@ -559,7 +692,7 @@ public class MilvusServiceImpl implements MilvusService {
559 692 }
560 693  
561 694 /**
562   - * 处理 Milvus 查询结果
  695 + * 处理 SearchResp 查询结果(向量相似度搜索)
563 696 */
564 697 private List<Map<String, Object>> processMilvusResults(SearchResp response) {
565 698 List<Map<String, Object>> results = new ArrayList<>();
... ... @@ -572,32 +705,84 @@ public class MilvusServiceImpl implements MilvusService {
572 705 log.warn("Milvus 搜索结果为空");
573 706 return results;
574 707 }
  708 +
575 709 // 遍历每个查询的结果集(通常只有一个查询)
576 710 for (List<SearchResp.SearchResult> resultList : searchResults) {
577 711 // 遍历每个搜索结果
578 712 for (SearchResp.SearchResult result : resultList) {
  713 + Map<String, Object> resultMap = new HashMap<>();
  714 +
579 715 // 获取实体字段数据
580 716 Map<String, Object> entity = result.getEntity();
581   - Map<String,Object> metadata = new HashMap<>();
582   - if(ObjectUtil.isNotEmpty(entity.get("metadata"))){
583   - JsonObject obj = (JsonObject) entity.get("metadata");
584   - metadata.putAll( jsonObjectToMap(obj));
  717 + if (entity != null && !entity.isEmpty()) {
  718 + resultMap.putAll(entity);
  719 + }
  720 +
  721 + // 处理 metadata 字段(如果是 JSON 对象)
  722 + if (resultMap.containsKey("metadata") && resultMap.get("metadata") instanceof JsonObject) {
  723 + JsonObject jsonObject = (JsonObject) resultMap.get("metadata");
  724 + Map<String, Object> metadataMap = jsonObjectToMap(jsonObject);
  725 + // 可以选择合并或替换
  726 + resultMap.putAll(metadataMap);
  727 + resultMap.remove("metadata"); // 移除原始的 metadata 对象
585 728 }
  729 +
586 730 // 获取相似度分数
587 731 Float score = result.getScore();
588 732 if (score != null) {
589   - metadata.put("score", score);
  733 + resultMap.put("score", score);
590 734 }
591   - // 将所有字段添加到结果中
592   -// item.putAll(entity);
593   - results.add(metadata);
  735 +
  736 + results.add(resultMap);
594 737 }
595 738 }
  739 +
596 740 log.info("处理完成,共 {} 条搜索结果", results.size());
597 741 return results;
598 742 }
599 743  
600 744 /**
  745 + * 处理 QueryResp 查询结果(全量查询)
  746 + */
  747 + private List<Map<String, Object>> processMilvusResults(QueryResp response) {
  748 + List<Map<String, Object>> results = new ArrayList<>();
  749 + if (response == null) {
  750 + log.warn("Milvus 响应为空");
  751 + return results;
  752 + }
  753 +
  754 + List<QueryResp.QueryResult> queryResults = response.getQueryResults();
  755 + if (queryResults == null || queryResults.isEmpty()) {
  756 + log.warn("Milvus 查询结果为空");
  757 + return results;
  758 + }
  759 +
  760 + // 遍历每个查询结果
  761 + for (QueryResp.QueryResult queryResult : queryResults) {
  762 + Map<String, Object> resultMap = new HashMap<>();
  763 +
  764 + // 获取实体字段数据
  765 + Map<String, Object> entity = queryResult.getEntity();
  766 + if (entity != null && !entity.isEmpty()) {
  767 + resultMap.putAll(entity);
  768 + }
  769 +
  770 + // 处理 metadata 字段(如果是 JSON 对象)
  771 + if (resultMap.containsKey("metadata") && resultMap.get("metadata") instanceof JsonObject) {
  772 + JsonObject jsonObject = (JsonObject) resultMap.get("metadata");
  773 + Map<String, Object> metadataMap = jsonObjectToMap(jsonObject);
  774 + resultMap.putAll(metadataMap);
  775 + resultMap.remove("metadata");
  776 + }
  777 +
  778 + results.add(resultMap);
  779 + }
  780 +
  781 + log.info("处理完成,共 {} 条查询结果", results.size());
  782 + return results;
  783 + }
  784 +
  785 + /**
601 786 * JsonObject 转 Map<String, Object>
602 787 */
603 788 public static Map<String, Object> jsonObjectToMap(JsonObject jsonObject) {
... ... @@ -693,7 +878,7 @@ public class MilvusServiceImpl implements MilvusService {
693 878 }
694 879 vectorText.append(" | ").append(fieldArr[0]).append(":").append(sText);
695 880 }
696   - vectorText.append(" ").append(sceneName);
  881 +// vectorText.append(" ").append(sceneName).append("数据");
697 882 }
698 883  
699 884  
... ...