Spring Boot集成Milvus快速入门demo

1.什么是Milvus?

Milvus 是一种高性能、高扩展性的向量数据库,可在从笔记本电脑到大型分布式系统等各种环境中高效运行。它既可以开源软件的形式提供,也可以云服务的形式提供。 Milvus 是 LF AI & Data Foundation 下的一个开源项目,以 Apache 2.0 许可发布。大多数贡献者都是高性能计算(HPC)领域的专家,擅长构建大型系统和优化硬件感知代码。核心贡献者包括来自 Zilliz、ARM、NVIDIA、AMD、英特尔、Meta、IBM、Salesforce、阿里巴巴和微软的专业人士

是什么让 Milvus 具有如此高的可扩展性

2022 年,Milvus 支持十亿级向量,2023 年,它以持续稳定的方式扩展到数百亿级,为 300 多家大型企业的大规模场景提供支持,包括 Salesforce、PayPal、Shopee、Airbnb、eBay、NVIDIA、IBM、AT&T、LINE、ROBLOX、Inflection 等。 Milvus 的云原生和高度解耦的系统架构确保了系统可以随着数据的增长而不断扩展:

highly-decoupled-architecture

  Milvus 本身是完全无状态的,因此可以借助 Kubernetes 或公共云轻松扩展。此外,Milvus 的各个组件都有很好的解耦,其中最关键的三项任务--搜索、数据插入和索引/压实--被设计为易于并行化的流程,复杂的逻辑被分离出来。这确保了相应的查询节点、数据节点和索引节点可以独立地向上和向下扩展,从而优化了性能和成本效率。

Milvus 支持的搜索类型

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

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

2.测试环境搭建

  • First, we’ll need an instance of Milvus DB. The easiest and quickest way is to get a fully managed free Milvus DB instance provided by Zilliz Cloud: Vector Database built for enterprise-grade AI applications - Zilliz
  • For this, we’ll need to register for a Zilliz cloud account and follow the documentation for creating a free DB cluster.

milvus

3.代码工程

实验目的

实现对Milvus向量数据库的的crud

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.1</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Milvus</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>
    <dependencies>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.milvus</groupId>
            <artifactId>milvus-sdk-java</artifactId>
            <version>2.4.1</version>
        </dependency>

    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <fork>true</fork>
                        <failOnError>false</failOnError>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.2</version>
                    <configuration>
                        <forkCount>0</forkCount>
                        <failIfNoTests>false</failIfNoTests>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

controller

package com.et.controller;

import com.et.service.HelloZillizVectorDBService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class HelloWorldController {
   @Autowired
   HelloZillizVectorDBService helloZillizVectorDBService;
    @RequestMapping("/hello")
    public Map<String, Object> showHelloWorld(){
        Map<String, Object> map = new HashMap<>();
      helloZillizVectorDBService.search();
        map.put("msg", "HelloWorld");
        return map;
    }
}

service

package com.et.service;


import io.milvus.client.MilvusServiceClient;
import io.milvus.grpc.DataType;
import io.milvus.grpc.DescribeCollectionResponse;
import io.milvus.grpc.MutationResult;
import io.milvus.grpc.SearchResults;
import io.milvus.param.*;
import io.milvus.param.collection.*;
import io.milvus.param.dml.InsertParam;
import io.milvus.param.dml.SearchParam;
import io.milvus.param.index.CreateIndexParam;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class HelloZillizVectorDBService {
   @Value("${uri}")
   public String uri;
   @Value("${token}")
   public String token;

    public  void search() {
        // connect to milvus
        final MilvusServiceClient milvusClient = new MilvusServiceClient(
                ConnectParam.newBuilder()
                        .withUri(uri)
                        .withToken(token)
                        .build());
        System.out.println("Connecting to DB: " + uri);
        // Check if the collection exists
        String collectionName = "book";
        R<DescribeCollectionResponse> responseR =
                milvusClient.describeCollection(DescribeCollectionParam.newBuilder().withCollectionName(collectionName).build());
        if (responseR.getData() != null) {
            milvusClient.dropCollection(DropCollectionParam.newBuilder().withCollectionName(collectionName).build());
        }
        System.out.println("Success!");
        // create a collection with customized primary field: book_id_field
        int dim = 64;
        FieldType bookIdField = FieldType.newBuilder()
                .withName("book_id")
                .withDataType(DataType.Int64)
                .withPrimaryKey(true)
                .withAutoID(false)
                .build();
        FieldType wordCountField = FieldType.newBuilder()
                .withName("word_count")
                .withDataType(DataType.Int64)
                .build();
        FieldType bookIntroField = FieldType.newBuilder()
                .withName("book_intro")
                .withDataType(DataType.FloatVector)
                .withDimension(dim)
                .build();
        CreateCollectionParam createCollectionParam = CreateCollectionParam.newBuilder()
                .withCollectionName(collectionName)
                .withDescription("my first collection")
                .withShardsNum(2)
                .addFieldType(bookIdField)
                .addFieldType(wordCountField)
                .addFieldType(bookIntroField)
                .build();
        System.out.println("Creating example collection: " + collectionName);
        System.out.println("Schema: " + createCollectionParam);
        milvusClient.createCollection(createCollectionParam);
        System.out.println("Success!");

        //insert data with customized ids
        Random ran = new Random();
        int singleNum = 1000;
        int insertRounds = 2;
        long insertTotalTime = 0L;
        System.out.println("Inserting " + singleNum * insertRounds + " entities... ");
        for (int r = 0; r < insertRounds; r++) {
            List<Long> book_id_array = new ArrayList<>();
            List<Long> word_count_array = new ArrayList<>();
            List<List<Float>> book_intro_array = new ArrayList<>();
            for (long i = r * singleNum; i < (r + 1) * singleNum; ++i) {
                book_id_array.add(i);
                word_count_array.add(i + 10000);
                List<Float> vector = new ArrayList<>();
                for (int k = 0; k < dim; ++k) {
                    vector.add(ran.nextFloat());
                }
                book_intro_array.add(vector);
            }
            List<InsertParam.Field> fields = new ArrayList<>();
            fields.add(new InsertParam.Field(bookIdField.getName(), book_id_array));
            fields.add(new InsertParam.Field(wordCountField.getName(), word_count_array));
            fields.add(new InsertParam.Field(bookIntroField.getName(), book_intro_array));
            InsertParam insertParam = InsertParam.newBuilder()
                    .withCollectionName(collectionName)
                    .withFields(fields)
                    .build();
            long startTime = System.currentTimeMillis();
            R<MutationResult> insertR = milvusClient.insert(insertParam);
            long endTime = System.currentTimeMillis();
            insertTotalTime += (endTime - startTime) / 1000.00;
        }
        System.out.println("Succeed in " + insertTotalTime + " seconds!");
        // flush data
        System.out.println("Flushing...");
        long startFlushTime = System.currentTimeMillis();
        milvusClient.flush(FlushParam.newBuilder()
                .withCollectionNames(Collections.singletonList(collectionName))
                .withSyncFlush(true)
                .withSyncFlushWaitingInterval(50L)
                .withSyncFlushWaitingTimeout(30L)
                .build());
        long endFlushTime = System.currentTimeMillis();
        System.out.println("Succeed in " + (endFlushTime - startFlushTime) / 1000.00 + " seconds!");

        // build index
        System.out.println("Building AutoIndex...");
        final IndexType INDEX_TYPE = IndexType.AUTOINDEX;   // IndexType
        long startIndexTime = System.currentTimeMillis();
        R<RpcStatus> indexR = milvusClient.createIndex(
                CreateIndexParam.newBuilder()
                        .withCollectionName(collectionName)
                        .withFieldName(bookIntroField.getName())
                        .withIndexType(INDEX_TYPE)
                        .withMetricType(MetricType.L2)
                        .withSyncMode(Boolean.TRUE)
                        .withSyncWaitingInterval(500L)
                        .withSyncWaitingTimeout(30L)
                        .build());
        long endIndexTime = System.currentTimeMillis();
        System.out.println("Succeed in " + (endIndexTime - startIndexTime) / 1000.00 + " seconds!");

        // load collection
        System.out.println("Loading collection...");
        long startLoadTime = System.currentTimeMillis();
        milvusClient.loadCollection(LoadCollectionParam.newBuilder()
                .withCollectionName(collectionName)
                .withSyncLoad(true)
                .withSyncLoadWaitingInterval(500L)
                .withSyncLoadWaitingTimeout(100L)
                .build());
        long endLoadTime = System.currentTimeMillis();
        System.out.println("Succeed in " + (endLoadTime - startLoadTime) / 1000.00 + " seconds");

        // search
        final Integer SEARCH_K = 2;                       // TopK
        final String SEARCH_PARAM = "{\"nprobe\":10}";    // Params
        List<String> search_output_fields = Arrays.asList("book_id", "word_count");
        for (int i = 0; i < 10; i++) {
            List<Float> floatList = new ArrayList<>();
            for (int k = 0; k < dim; ++k) {
                floatList.add(ran.nextFloat());
            }
            List<List<Float>> search_vectors = Collections.singletonList(floatList);
            SearchParam searchParam = SearchParam.newBuilder()
                    .withCollectionName(collectionName)
                    .withMetricType(MetricType.L2)
                    .withOutFields(search_output_fields)
                    .withTopK(SEARCH_K)
                    .withVectors(search_vectors)
                    .withVectorFieldName(bookIntroField.getName())
                    .withParams(SEARCH_PARAM)
                    .build();
            long startSearchTime = System.currentTimeMillis();
            R<SearchResults> search = milvusClient.search(searchParam);
            long endSearchTime = System.currentTimeMillis();
            System.out.println("Searching vector: " + search_vectors);
            System.out.println("Result: " + search.getData().getResults().getFieldsDataList());
            System.out.println("search " + i + " latency: " + (endSearchTime - startSearchTime) / 1000.00 + " seconds");
        }

        milvusClient.close();
    }

}

application.yaml

用实际的值替换下面的参数

uri = https://in01-XXXXXXXXXXXXX.aws-us-west-2.vectordb.zillizcloud.com:XXXXX
token = db_admin:password (or ApiKey)

只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

4.测试

启动Spring Boot应用,访问http://127.0.0.1:8080/hello,查看控制台输出日志

 Connecting to DB: https://in03-258dd5ae260ce1b.serverless.gcp-us-west1.cloud.zilliz.com
2024-09-25T21:29:30.636+08:00 ERROR 52861 --- [nio-8080-exec-2] i.m.client.AbstractMilvusGrpcClient : DescribeCollectionRequest collectionName:book failed, error code: 100, reason: can't find collection[database=db_258dd5ae260ce1b][collection=book]
2024-09-25T21:29:30.641+08:00 ERROR 52861 --- [nio-8080-exec-2] i.m.client.AbstractMilvusGrpcClient : DescribeCollectionRequest collectionName:book failed! Exception:{}

io.milvus.exception.ServerException: can't find collection[database=db_258dd5ae260ce1b][collection=book]
 at io.milvus.client.AbstractMilvusGrpcClient.handleResponse(AbstractMilvusGrpcClient.java:347) ~[milvus-sdk-java-2.3.4.jar:na]
 at io.milvus.client.AbstractMilvusGrpcClient.describeCollection(AbstractMilvusGrpcClient.java:655) ~[milvus-sdk-java-2.3.4.jar:na]
 at io.milvus.client.MilvusServiceClient.lambda$describeCollection$9(MilvusServiceClient.java:402) ~[milvus-sdk-java-2.3.4.jar:na]
 at io.milvus.client.MilvusServiceClient.retry(MilvusServiceClient.java:285) ~[milvus-sdk-java-2.3.4.jar:na]
 at io.milvus.client.MilvusServiceClient.describeCollection(MilvusServiceClient.java:402) ~[milvus-sdk-java-2.3.4.jar:na]
 at com.et.service.HelloZillizVectorDBService.search(HelloZillizVectorDBService.java:37) ~[classes/:na]
 at com.et.controller.HelloWorldController.showHelloWorld(HelloWorldController.java:18) ~[classes/:na]
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
 at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
 at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:262) ~[spring-web-6.1.2.jar:6.1.2]
 at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:190) ~[spring-web-6.1.2.jar:6.1.2]
 at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.2.jar:6.1.2]
 at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:917) ~[spring-webmvc-6.1.2.jar:6.1.2]
 at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:829) ~[spring-webmvc-6.1.2.jar:6.1.2]
 at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.2.jar:6.1.2]
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.2.jar:6.1.2]
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.2.jar:6.1.2]
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.2.jar:6.1.2]
 at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.1.2.jar:6.1.2]
 at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.17.jar:6.0]
 at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.2.jar:6.1.2]
 at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.17.jar:6.0]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.17.jar:10.1.17]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.2.jar:6.1.2]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.2.jar:6.1.2]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.2.jar:6.1.2]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.2.jar:6.1.2]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.2.jar:6.1.2]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.2.jar:6.1.2]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.17.jar:10.1.17]
 at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]

Success!
Creating example collection: book
Schema: CreateCollectionParam(collectionName=book, shardsNum=2, description=my first collection, fieldTypes=[FieldType{name='book_id', type='Int64', elementType='None', primaryKey=true, partitionKey=false, autoID=false, params={}}, FieldType{name='word_count', type='Int64', elementType='None', primaryKey=false, partitionKey=false, autoID=false, params={}}, FieldType{name='book_intro', type='FloatVector', elementType='None', primaryKey=false, partitionKey=false, autoID=false, params={dim=64}}], partitionsNum=0, consistencyLevel=BOUNDED, databaseName=null, enableDynamicField=false)
Success!
Inserting 2000 entities... 
Succeed in 1 seconds!
Flushing...
Succeed in 3.019 seconds!
Building AutoIndex...
Succeed in 3.092 seconds!
Loading collection...
Succeed in 1.915 seconds
Searching vector: [[0.9944244, 0.693386, 0.23255765, 0.25712538, 0.8882742, 0.31521088, 0.10415316, 0.63687223, 0.23532659, 0.9057376, 0.23146588, 0.7598192, 0.18651527, 0.22246557, 0.71210265, 0.9853572, 0.7285811, 0.49920946, 0.5757665, 0.9907576, 0.6746712, 0.53398585, 0.3538667, 0.90167266, 0.09474373, 0.24573046, 0.19975495, 0.9486663, 0.38426965, 0.94270027, 0.0389961, 0.3591758, 0.092348695, 0.35975152, 0.0286901, 0.39673442, 0.59137595, 0.9894001, 0.7167906, 0.92300236, 0.95593584, 0.041143477, 0.26055408, 0.37320316, 0.64292294, 0.9690605, 0.8847745, 0.78260505, 0.92037845, 0.3789205, 0.13551015, 0.30201513, 0.49969083, 0.9982949, 0.066904426, 0.2057795, 0.58327323, 0.5174314, 0.14389539, 0.5790425, 0.9743603, 0.50154245, 0.6616634, 0.91518396]]
Result: [type: Int64
field_name: "book_id"
scalars {
 long_data {
 data: 1901
 data: 420
 }
}
field_id: 100
, type: Int64
field_name: "word_count"
scalars {
 long_data {
 data: 11901
 data: 10420
 }
}
field_id: 101
]
search 0 latency: 0.884 seconds
Searching vector: [[0.012040913, 0.26888567, 0.8862797, 0.6432027, 0.72606975, 0.9214382, 0.8760127, 0.91277415, 0.6635162, 0.41956168, 0.21806747, 0.7068079, 0.562168, 0.28791857, 0.33324522, 0.83323824, 0.25118947, 0.8217658, 0.8863152, 0.5157847, 0.49335915, 0.39096528, 0.47110444, 0.9944315, 0.66889536, 0.98959273, 0.59788084, 0.7379387, 0.2901945, 0.6934935, 0.031101823, 0.93097365, 0.9596271, 0.32376093, 0.34571892, 0.8362285, 0.99687576, 0.7937399, 0.78078747, 0.34658694, 0.10428548, 0.2792738, 0.8640791, 0.57405174, 0.9725894, 0.20060968, 0.10779828, 0.101415455, 0.09755844, 0.7593852, 0.28356135, 0.6208364, 0.55110157, 0.42079234, 0.27782845, 0.06248188, 0.37675542, 0.7703235, 0.41342628, 0.07876682, 0.3361001, 0.8730568, 0.9582374, 0.38860106]]
Result: [type: Int64
field_name: "book_id"
scalars {
 long_data {
 data: 118
 data: 776
 }
}
field_id: 100
, type: Int64
field_name: "word_count"
scalars {
 long_data {
 data: 10118
 data: 10776
 }
}
field_id: 101
]
search 1 latency: 0.193 seconds
Searching vector: [[0.17430764, 0.9034548, 0.59125566, 0.13526762, 0.48277777, 0.9429901, 0.07483035, 0.09548402, 0.7757748, 0.5250427, 0.70900095, 0.46090156, 0.055408716, 0.5705429, 0.19141757, 0.5524303, 0.9825838, 0.6484894, 0.84965557, 0.41863292, 0.69617915, 0.123098195, 0.3800782, 0.8989199, 0.30235797, 0.33991778, 0.9502303, 0.6279421, 0.3922888, 0.94838214, 0.98462456, 0.23758143, 0.5195748, 0.16518217, 0.044407308, 0.9360681, 0.086349785, 0.9243839, 0.7705846, 0.85942554, 0.33542854, 0.6248715, 0.9321932, 0.3886962, 0.23936534, 0.5275571, 0.7020884, 0.68789816, 0.70815116, 0.7435949, 0.5740872, 0.36369282, 0.22608125, 0.42592448, 0.9893665, 0.59022135, 0.37368262, 0.9808166, 0.113725126, 0.63403445, 0.6192569, 0.3703097, 0.11013746, 0.19765383]]
Result: [type: Int64
field_name: "word_count"
scalars {
 long_data {
 data: 11983
 data: 10315
 }
}
field_id: 101
, type: Int64
field_name: "book_id"
scalars {
 long_data {
 data: 1983
 data: 315
 }
}
field_id: 100
]
search 2 latency: 0.21 seconds
Searching vector: [[0.78146076, 0.4127342, 0.19565648, 0.7598609, 0.0024149418, 0.20477176, 0.2239834, 0.40071744, 0.34123564, 0.69816893, 0.16385543, 0.8746263, 0.93988293, 0.14641893, 0.77087975, 0.74109954, 0.44419652, 0.686166, 0.8017639, 0.62660855, 0.12844962, 0.09513128, 0.0733701, 0.50885594, 0.19533062, 0.6489767, 0.5061082, 0.76457673, 0.556717, 0.62532073, 0.44644332, 0.47170228, 0.17381704, 0.031323075, 0.1744278, 0.61520636, 0.7062351, 0.48471195, 0.659993, 0.8125965, 0.8243918, 0.2953208, 0.6301986, 0.48987025, 0.44276655, 0.87922597, 0.59580773, 0.03247899, 0.2750023, 0.91016316, 0.109629214, 0.8797219, 0.26653385, 0.55840206, 0.5943634, 0.28695053, 0.4747029, 0.7866449, 0.19065481, 0.15052843, 0.017061412, 0.73239404, 0.29625612, 0.86883324]]
Result: [type: Int64
field_name: "word_count"
scalars {
 long_data {
 data: 11674
 data: 11420
 }
}
field_id: 101
, type: Int64
field_name: "book_id"
scalars {
 long_data {
 data: 1674
 data: 1420
 }
}
field_id: 100
]
search 3 latency: 0.234 seconds
Searching vector: [[0.5506256, 0.4888333, 0.55734605, 0.33249807, 0.9612315, 0.14942867, 0.74893725, 0.32297194, 0.19399291, 0.3686679, 0.16189837, 0.51538646, 0.4324317, 0.24171656, 0.17148066, 0.98530066, 0.70252293, 0.36399698, 0.67156136, 0.30545527, 0.8341777, 0.10815537, 0.04843366, 0.5751087, 0.030209243, 0.5765392, 0.56931233, 0.7783963, 0.87335634, 0.24376905, 0.15837216, 0.8376091, 0.8253407, 0.90347946, 0.91477525, 0.3711217, 0.34623754, 0.3486765, 0.7336032, 0.1333232, 0.9737603, 0.9348897, 0.56583005, 0.19536161, 0.66466415, 0.25348592, 0.1945247, 0.30146033, 0.6067432, 0.0488891, 0.61155295, 0.32729924, 0.58033705, 0.9833621, 0.805477, 0.0863865, 0.88150877, 0.13743609, 0.8735751, 0.730011, 0.2418676, 0.24961507, 0.15848696, 0.90943843]]
Result: [type: Int64
field_name: "book_id"
scalars {
 long_data {
 data: 632
 data: 71
 }
}
field_id: 100
, type: Int64
field_name: "word_count"
scalars {
 long_data {
 data: 10632
 data: 10071
 }
}
field_id: 101
]
search 4 latency: 0.246 seconds
Searching vector: [[0.097262084, 0.67786944, 0.5956394, 0.599271, 0.80228144, 0.20551127, 0.60712826, 0.7927536, 0.8707964, 0.92879516, 0.8600838, 0.088315904, 0.28391147, 0.13210869, 0.6447914, 0.79745305, 0.1630668, 0.87363887, 0.8451723, 0.56345624, 0.30312908, 0.8302696, 0.7499766, 0.42542475, 0.9217818, 0.16116339, 0.76864123, 0.7699597, 0.55911744, 0.88660645, 0.4057927, 0.05212158, 0.9849399, 0.6994747, 0.25052422, 0.5464197, 0.6989017, 0.6539669, 0.8416681, 0.60720086, 0.67637247, 0.74851876, 0.87226254, 0.015863419, 0.2851053, 0.741167, 0.5423461, 0.4004978, 0.21673638, 0.32579643, 0.90930575, 0.5031407, 0.11341238, 0.042031705, 0.72256076, 0.20273715, 0.67203254, 0.49100053, 0.5708503, 0.78067535, 0.053472757, 0.8504045, 0.77535784, 0.43355346]]
Result: [type: Int64
field_name: "book_id"
scalars {
 long_data {
 data: 1240
 data: 1074
 }
}
field_id: 100
, type: Int64
field_name: "word_count"
scalars {
 long_data {
 data: 11240
 data: 11074
 }
}
field_id: 101
]
search 5 latency: 0.233 seconds
Searching vector: [[0.6666099, 0.60750645, 0.5930602, 0.62844944, 0.91999257, 0.40563875, 0.16784662, 0.58380336, 0.49874693, 0.9921237, 0.70105964, 0.109129846, 0.62001497, 0.29218578, 0.38023782, 0.80481774, 0.61428535, 0.45924222, 0.2801816, 0.40553528, 0.9678988, 0.4772452, 0.26234365, 0.934155, 0.6174237, 0.14148414, 0.5784021, 0.54518217, 0.11126441, 0.41204536, 0.61628705, 0.09558219, 0.12766111, 0.6261982, 0.899587, 0.8454346, 0.46918148, 0.5451731, 0.904986, 0.41042298, 0.82801545, 0.8856106, 0.5411191, 0.45282567, 0.448133, 0.8004736, 0.73305, 0.28807688, 0.99202037, 0.69817233, 0.67967457, 0.9214035, 0.97179586, 0.05739242, 0.15004623, 0.2254278, 0.6256416, 0.25962013, 0.015357256, 0.37749702, 0.037437856, 0.43823433, 0.88566333, 0.03802377]]
Result: [type: Int64
field_name: "book_id"
scalars {
 long_data {
 data: 840
 data: 758
 }
}
field_id: 100
, type: Int64
field_name: "word_count"
scalars {
 long_data {
 data: 10840
 data: 10758
 }
}
field_id: 101
]
search 6 latency: 0.204 seconds
Searching vector: [[0.11513382, 0.46449423, 0.74709874, 0.45208257, 0.09473729, 0.254663, 0.34211916, 0.9703239, 0.93299186, 0.9023329, 0.3711759, 0.8269761, 0.032090902, 0.7948698, 0.5412331, 0.18797356, 0.52153504, 0.9574906, 0.86989266, 0.9373586, 0.95098126, 0.74318993, 0.25189924, 0.7419808, 0.94729316, 0.5275025, 0.08891839, 0.100687325, 0.71073514, 0.915546, 0.20827055, 0.21283334, 0.29924893, 0.7821449, 0.4894712, 0.10083097, 0.43401027, 0.16695005, 0.6697829, 0.8920079, 0.09012061, 0.073818564, 0.005478561, 0.046307027, 0.77760696, 0.7813985, 0.57121813, 0.53898925, 0.112255454, 0.57960665, 0.43604386, 0.14278823, 0.79370797, 0.38984406, 0.16432655, 0.46382785, 0.29833382, 0.50633746, 0.6599931, 0.87258536, 0.6334079, 0.47853124, 0.3620978, 0.9284326]]
Result: [type: Int64
field_name: "word_count"
scalars {
 long_data {
 data: 11609
 data: 10760
 }
}
field_id: 101
, type: Int64
field_name: "book_id"
scalars {
 long_data {
 data: 1609
 data: 760
 }
}
field_id: 100
]
search 7 latency: 0.201 seconds
Searching vector: [[0.14196914, 0.72220755, 0.97196966, 0.95760065, 0.17740268, 0.84783286, 0.96259207, 0.6342059, 0.14442027, 0.49199748, 0.008492172, 0.397287, 0.9179648, 0.960828, 0.5513112, 0.36929417, 0.5710163, 0.5876399, 0.05758536, 0.8194362, 0.061840713, 0.98121184, 0.1594106, 0.72564113, 0.52452654, 0.42187476, 0.027037859, 0.3591584, 0.8754618, 0.4417299, 0.68962467, 0.16419351, 0.9725907, 0.0099541545, 0.98403805, 0.29020512, 0.7518712, 0.9071815, 0.71259576, 0.6060254, 0.90245855, 0.502836, 0.97288334, 0.67282623, 0.34302354, 0.7001372, 0.48336947, 0.15780938, 0.21866882, 0.7550309, 0.7676532, 0.35363984, 0.37162405, 0.74286896, 0.9311386, 0.5419771, 0.34793264, 0.8912447, 0.32318318, 0.75553536, 0.41343224, 0.8355903, 0.93488806, 0.29507792]]
Result: [type: Int64
field_name: "book_id"
scalars {
 long_data {
 data: 443
 data: 1132
 }
}
field_id: 100
, type: Int64
field_name: "word_count"
scalars {
 long_data {
 data: 10443
 data: 11132
 }
}
field_id: 101
]
search 8 latency: 0.227 seconds
Searching vector: [[0.77036685, 0.11818504, 0.9503699, 0.029416382, 0.02396065, 0.23895812, 0.41341382, 0.82225484, 0.8573582, 0.09137666, 0.6607858, 0.3046307, 0.07275897, 0.25788748, 0.6302589, 0.95142424, 0.46371943, 0.99155724, 0.7007737, 0.9712237, 0.043981254, 0.6340834, 0.6424302, 0.7176585, 0.6954333, 0.091201425, 0.026640236, 0.15468991, 0.36369103, 0.9462943, 0.0063298345, 0.72643405, 0.15416229, 0.9989488, 0.3602597, 0.8026867, 0.52236784, 0.8901442, 0.69515526, 0.59382325, 0.7458346, 0.95818526, 0.5083475, 0.09321368, 0.8753361, 0.26350176, 0.6790923, 0.6423713, 0.833, 0.5457574, 0.8288555, 0.1950497, 0.52434474, 0.7186958, 0.77294624, 0.24331266, 0.10928261, 0.8677729, 0.084388554, 0.7637791, 0.6102848, 0.8594893, 0.16542625, 0.9389486]]
Result: [type: Int64
field_name: "book_id"
scalars {
 long_data {
 data: 1938
 data: 668
 }
}
field_id: 100
, type: Int64
field_name: "word_count"
scalars {
 long_data {
 data: 11938
 data: 10668
 }
}
field_id: 101
]
search 9 latency: 1.076 seconds

5.引用

以下是一个MilvusJava示例代码: ```java import io.milvus.client.*; import java.util.Arrays; import java.util.List; public class MilvusDemo { public static void main(String[] args) { // 设置Milvus服务器的IP地址和端口号 String host = "127.0.0.1"; int port = 19530; // 创建Milvus客户端 MilvusClient client = new MilvusGrpcClient(); // 连接到Milvus服务器 ConnectParam connectParam = new ConnectParam.Builder() .withHost(host) .withPort(port) .build(); Response connectResponse = client.connect(connectParam); if (!connectResponse.ok()) { System.out.println("连接到Milvus服务器失败:" + connectResponse.getMessage()); return; } // 创建一个Milvus集合 String collectionName = "my_collection"; FieldSchema vectorField = new FieldSchema.Builder("vector", DataType.FLOAT_VECTOR, 128).build(); CollectionMapping collectionMapping = new CollectionMapping.Builder(collectionName, Arrays.asList(vectorField)).build(); Response createCollectionResponse = client.createCollection(collectionMapping); if (!createCollectionResponse.ok()) { System.out.println("创建Milvus集合失败:" + createCollectionResponse.getMessage()); return; } // 插入向量数据 List<FloatVector> vectors = Arrays.asList( new FloatVector(Arrays.asList(0.1f, 0.2f, 0.3f)), new FloatVector(Arrays.asList(0.4f, 0.5f, 0.6f)), new FloatVector(Arrays.asList(0.7f, 0.8f, 0.9f)) ); InsertParam insertParam = new InsertParam.Builder(collectionName, vectors).build(); Response insertResponse = client.insert(insertParam); if (!insertResponse.ok()) { System.out.println("插入向量数据失败:" + insertResponse.getMessage()); return; } // 查询相似的向量 List<FloatVector> queryVectors = Arrays.asList( new FloatVector(Arrays.asList(0.2f, 0.3f, 0.4f)) ); SearchParam searchParam = new SearchParam.Builder(collectionName, queryVectors, 1).build(); Response searchResponse = client.search(searchParam); if (!searchResponse.ok()) { System.out.println("查询相似的向量失败:" + searchResponse.getMessage()); return; } // 打印查询结果 SearchResult searchResult = searchResponse.getSearchResult(); List<List<SearchResult.VectorData>> vectorDataList = searchResult.getVectorDataList(); for (List<SearchResult.VectorData> vectorData : vectorDataList) { for (SearchResult.VectorData data : vectorData) { System.out.println("相似的向量:" + data.getVector()); System.out.println("相似度:" + data.getDistance()); } } // 断开与Milvus服务器的连接 Response disconnectResponse = client.disconnect(); if (!disconnectResponse.ok()) { System.out.println("断开与Milvus服务器的连接失败:" + disconnectResponse.getMessage()); return; } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HBLOGA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值