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

1.前提提要:java的pom 版本为:2.4.9 milvus 版本是:2.4.13-hotfix

2.先来工具类方法

c 复制代码
    /**
     * 向量搜索
     * @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.包装的请求条件

c 复制代码
@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.向量数据的转换

c 复制代码
   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连接对象,具体可看之前的博客

c 复制代码
            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

和上次使用的经验一样,肯定没有最新的包,果然,换成最新的谷歌的包问题解决

c 复制代码
        <!--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>
相关推荐
麦兜*2 小时前
Spring Boot集成方案 + Elasticsearch向量检索,语义搜索核弹
java·spring boot·python·spring·elasticsearch·spring cloud·系统架构
柊二三4 小时前
spring boot开发中的资源处理等问题
java·spring boot·后端
一枚小小程序员哈4 小时前
基于springboot的宠物商城设计与实现
java·spring boot·spring·eclipse·tomcat·maven·宠物
风与尘6 小时前
RabbitMQ延时队列的两种实现方式
spring boot·分布式·中间件·rabbitmq
_码农121386 小时前
简单spring boot项目,之前练习的,现在好像没有达到效果
java·spring boot·后端
巴拉巴巴巴拉7 小时前
Spring Boot 整合 Web 开发全攻略
spring boot
写代码的比利9 小时前
Spring 调试终于不再痛苦了
spring boot·spring·intellij idea
一只爱撸猫的程序猿11 小时前
构建一个简单的亿级数据迁移方案案例
spring boot·数据分析·ai编程
风象南12 小时前
告别YAML,在SpringBoot中用数据库配置替代配置文件
spring boot·后端
枣伊吕波12 小时前
十一、请求响应-请求:简单参数和实体参数(简单实体参数与复杂实体参数)
java·spring boot·后端