当前位置: 首页 > news >正文

springboot milvus search向量相似度查询 踩坑使用经验

1.前提提要:java的pom 版本为:2.4.9 milvus 版本是:2.4.13-hotfix
2.先来工具类方法

    /**
     * 向量搜索
     * @param client
     * @param query
     * @return
     */
    public SearchResp search(@NonNull MilvusClientV2 client, @NonNull VectorCondition query) {
        final List<BaseVector> data = query.getData();
        if (CollectionUtils.isEmpty(data)) {
            return null;
        }
        SearchReq.SearchReqBuilder searchReqBuilder = SearchReq.builder().collectionName(query.getCollectionName())
                .data(data);
        if (query.getTopK() > 0) {
            searchReqBuilder.topK(query.getTopK());
        }
        if (!StringUtils.isEmpty(query.getAnnsField())) {
            searchReqBuilder.annsField(query.getAnnsField());
        }
        if (!CollectionUtils.isEmpty(query.getSearchParams())) {
            searchReqBuilder.searchParams(query.getSearchParams());
        }
        if (!CollectionUtils.isEmpty(query.getPartitionNames())) {
            searchReqBuilder.partitionNames(query.getPartitionNames());
        }
        if (!CollectionUtils.isEmpty(query.getOutputFields())) {
            searchReqBuilder.outputFields(query.getOutputFields());
        } else {
            searchReqBuilder.outputFields(Collections.singletonList("*"));
        }
        if (StringUtils.isNotBlank(query.getFilter())) {
            searchReqBuilder.filter(query.getFilter());
        }
        final SearchResp search = client.search(searchReqBuilder.build());
        return search;
    }

3.包装的请求条件

@Data
@Builder
public class VectorCondition {
    //现有集合的名称。
    @NonNull
    String collectionName;
    String partitionName;
    //分区名称列表。
    List<String> partitionNames;
    //返回每个实体中包含的字段名称列表。
    //该值默认为None。如果未指定,则选择集合中的所有字段作为输出字段。
    List<String> outputFields;
    //要查询的实体的 ID。
    List<Object> ids;
    //用于筛选匹配实体的标量筛选条件。
    //您可以将此参数设置为空字符串以跳过标量过滤。要构建标量过滤条件,请参阅布尔表达式规则。
    String filter;
    //目标集合的一致性级别。
    //该值默认为创建当前集合时指定的值,选项包括Strong ( 0 )、Bounded ( 1 )、Session ( 2 ) 和Finally ( 3 )。
    ConsistencyLevel consistencyLevel;
    //查询结果中要跳过的记录数。
    //您可以结合使用此参数来limit启用分页。
    //该值的总和limit应小于 16,384。
    long offset;
    //查询结果中返回的记录数。
    //您可以结合使用此参数来offset启用分页。
    //该值的总和offset应小于 16,384。
    long limit;
    //矢量字段的名称,当有多个矢量字段时使用。如果只存在一个矢量字段,我们将直接使用它
    String annsField;
    //搜索结果中返回的记录数。此参数使用与参数相同的语法limit,因此您只应设置其中一个。
    //您可以结合使用此参数来offset启用分页。
    //该值的总和offset应小于 16,384。
    int topK;
    //向量嵌入的列表。
    //Milvus 搜索与指定的向量嵌入最相似的向量嵌入。
    List<BaseVector> data;
    //插入的向量。
    List<JsonObject> dataJson;
    //Milvus 将计算出的距离四舍五入到的小数位数。
    //该值默认为-1,表示 Milvus 跳过对计算距离进行四舍五入并返回原始值。
    int roundDecimal;
    //此操作特有的参数设置。
    //metric_type (字符串)
    //应用于此操作的度量类型。这应该与索引上面指定的矢量字段时使用的类型相同。
    //可能的值是L2、IP和COSINE。
    //半径(浮点数)
    //确定最小相似度的阈值,设置metric_type为时L2,确保该值大于range_filter的值,否则,该值应小于range_filter的值。
    //范围过滤器(浮点数)
    //将搜索范围缩小到特定相似度范围内的向量。设置metric_type为IP或 时COSINE,请确保此值大于 radius 。否则,此值应小于radius。
    Map<String, Object> searchParams;
    //是否在相似性搜索期间忽略增长的片段。
    boolean ignoreGrowing;
    //设置字段名称以对结果进行分组。
    String groupByFieldName;
}


4.向量数据的转换

   final List<Object> data;
     // 使用Stream API进行转换
        List<Float> floatList = data.stream()
                .map(obj -> obj instanceof Double ? ((Double) obj).floatValue() : (Float) obj) // 转换为Float
                .collect(Collectors.toList()); // 收集结果到新的列表

        List<BaseVector> requestData = new ArrayList<>();
        final FloatVec baseVector = new FloatVec(floatList);
        requestData.add(baseVector);
        Map<String, Object> params = new HashMap<>();
        params.put("nprobe", "1024");
        params.put("radius", 0.5f);
        final VectorCondition vector = VectorCondition.builder()
                .collectionName("xxxxx")
                .annsField("vector")
                .topK(1)
                .searchParams(params)
                .data(requestData)
                .build();
        SearchResp searchR = (SearchResp) milvusUtil.execute("search", vector);
        final List<List<SearchResp.SearchResult>> searchResults = searchR.getSearchResults();
        for (List<SearchResp.SearchResult> results : searchResults) {
            for (SearchResp.SearchResult result : results) {
                System.out.printf("ID: %s, Score: %f, %s\n", result.getId(), result.getScore(), result.getEntity().toString());
            }
        }

使用线程池获取MilvusClient连接对象,具体可看之前的博客

            case MilvusUtil.SEARCH:
                result = this.search(milvusClientPool.getClient(SEARCH), vectorCondition);
                break;

报错
Caused by: java.lang.ClassNotFoundException: com.google.gson.ToNumberPolicy
原因:java.lang.ClassNotFoundException:com.google.gson.ToNumberPolicy
和上次使用的经验一样,肯定没有最新的包,果然,换成最新的谷歌的包问题解决

        <!--milvus-->
        <dependency>
            <groupId>io.milvus</groupId>
            <artifactId>milvus-sdk-java</artifactId>
            <version>2.4.9</version>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>gson</artifactId>
                    <groupId>com.google.gson</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>26.0-jre</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.11.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.9</version> <!-- 或者更新版本 -->
        </dependency>

在这里插入图片描述

相关文章:

  • 看盘细节系列 篇五:盘中突然拉升涨停的特征分析
  • 爱普生SG2016CAN晶振优势和多领域应用
  • C语音组播收发
  • Langchain 提示词(Prompt)
  • Android数据加密方案
  • 基于百分位裁剪(percentile clipping)归一化方法
  • node-ddk,electron 组件, 打开新窗口
  • 「宇树科技」13家核心零部件供应商梳理!
  • 对顶堆简介 → 第K大问题 + topK问题
  • 设计心得——作用域处理
  • Cross-Site Scripting: DOM $(_config.elem).html 解决问题
  • 【C++11】左值引用、右值引用、移动语义和完美转发
  • 预测性维护:Ubuntu边缘计算机如何降低电梯故障率
  • rust Send Sync 以及对象安全和对象不安全
  • acwing1295. X的因子链
  • Kubernetes - Pod控制器 - Deployment - 金丝雀部署
  • OpenHarmony 入门——ArkUI 跨页面数据同步和页面级UI状态存储LocalStorage小结(二)
  • java使用Apache POI 操作word文档
  • leetcode684.冗余连接
  • 021-TCMalloc
  • 欠债七十万后,一个乡镇驿站站长的中年心事
  • 陕西省安康市汉阴县县长陈永乐已任汉阴县委书记
  • 国际能源署:全球电动汽车市场强劲增长,中国市场继续领跑
  • GDP逼近五千亿,向海图强,对接京津,沧州剑指沿海经济强市
  • 王毅会见巴西外长维埃拉、总统首席特别顾问阿莫林
  • 男子发寻母视频被警方批评教育,律师:发寻亲信息是正当行为