PostgreSQL【应用 01】使用Vector插件实现向量相似度查询(Docker部署的PostgreSQL安装pgvector插件说明)和Milvus向量库对比

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核8GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: PostgreSQL【应用 01】使用Vector插件实现向量相似度查询(Docker部署的PostgreSQL安装pgvector插件说明)和Milvus向量库对比

1.背景

想要实现一个图片特征向量相似度搜索的功能,项目使用的是Java开发,数据库是PostgreSQL,可选择的方案有:

  • Vector database - Milvus部署方便,有可视化界面Attu,有JavaSDK(但是需要专门部署)。
  • PostgreSQL插件(Cube 支持100维,Pase 支持512维,Vector 支持16000维)。

由于提取的图片的特征向量有1024维,所以只能使用Milvus和PostgreSQL插件Vector了。

2.应用

2.1 Milvus

Milvus官网有详细的安装流程和代码这里不再赘述,使用Docker安装,版本为2.2.9,这里为大家提供一个简单的工具类,数据库连接参数没有参数化,小伙伴们可以优化,对结果数据进行了简单的格式化:

结果封装:

@Data
@Builder
public class MilvusRes {
    public float score;
    public String imagePath;
}

工具类:

@Slf4j
@Component
public class MilvusUtil {
    public MilvusServiceClient milvusServiceClient;
    @PostConstruct
    private void connectToServer() {
        milvusServiceClient = new MilvusServiceClient(
                ConnectParam.newBuilder()
                        .withHost("your service host")
                        .withPort(19530)
                        .build());
        // 加载数据
        LoadCollectionParam faceSearchNewLoad = LoadCollectionParam.newBuilder().withCollectionName("CollectionName").build();
        R<RpcStatus> rpcStatusR = milvusServiceClient.loadCollection(faceSearchNewLoad);
        log.info("Milvus LoadCollection [{}]", rpcStatusR.getStatus());
    }
    public int insertDataToMilvus(String id, String path, float[] feature) {
        List<InsertParam.Field> fields = new ArrayList<>();
        List<Float> featureList = new ArrayList<>(feature.length);
        for (float v : feature) {
            featureList.add(v);
        }
        fields.add(new InsertParam.Field("field1", Collections.singletonList(id)));
        fields.add(new InsertParam.Field("field2", Collections.singletonList(path)));
        fields.add(new InsertParam.Field("field3", Collections.singletonList(featureList)));
        InsertParam insertParam = InsertParam.newBuilder()
                .withCollectionName("CollectionName")
                //.withPartitionName("novel")
                .withFields(fields)
                .build();
        R<MutationResult> insert = milvusServiceClient.insert(insertParam);
        return insert.getStatus();
    }
    public List<MilvusRes> searchImageByFeature(float[] feature) {
        List<Float> featureList = new ArrayList<>(feature.length);
        for (float v : feature) {
            featureList.add(v);
        }
        List<String> queryOutputFields = Arrays.asList("field");
        SearchParam faceSearch = SearchParam.newBuilder()
                .withCollectionName("CollectionName")
                .withMetricType(MetricType.IP)
                .withVectorFieldName("VectorFieldName")
                .withVectors(Collections.singletonList(featureList))
                .withOutFields(queryOutputFields)
                .withTopK(10).build();
        // 执行搜索
        long l = System.currentTimeMillis();
        R<SearchResults> respSearch = milvusServiceClient.search(faceSearch);
        log.info("MilvusServiceClient.search cost [{}]", System.currentTimeMillis() - l);
        // 解析结果数据
        SearchResultData results = respSearch.getData().getResults();
        int scoresCount = results.getScoresCount();
        SearchResultsWrapper wrapperSearch = new SearchResultsWrapper(results);
        List<MilvusRes> milvusResList = new ArrayList<>();
        for (int i = 0; i < scoresCount; i++) {
            float score = wrapperSearch.getIDScore(0).get(i).getScore();
            Object imagePath = wrapperSearch.getFieldData("field1", 0).get(i);
            MilvusRes milvusRes = MilvusRes.builder().score(score).imagePath(imagePath.toString()).build();
            milvusResList.add(milvusRes);
        }
        return milvusResList;
    }
}

数量如图:

性能测试结果如下:

MilvusServiceClient.search cost [24]

2.2 Vector

基础信息以下网站都有说明,这里不再赘述。

数据库PostgreSQL使用的是Docker部署,版本为12.12,插件安装流程如下:

# 进入容器
docker exec -it CONTAINER ID /bin/bash
# 1.更新 apt-get 
apt-get update
# 未更新直接安装会报错
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package postgresql-12-postgis-3
E: Unable to locate package postgresql-12-postgis-3-dbgsym
E: Unable to locate package postgresql-12-postgis-3-scripts
# 2.安装插件
apt-get install postgresql-12-pgvector

数据库操作:

-- 添加 vector 扩展
CREATE EXTENSION vector;
-- 查询可使用的扩展
SELECT * FROM pg_available_extensions;
-- 创建表
CREATE TABLE "public"."test" ( 
  "field1" VARCHAR ( 64 ), 
  "field2" VARCHAR ( 128 ), 
  "field3" vector ( 1024 ), 
  CONSTRAINT "test_pkey" PRIMARY KEY ( "field1" ) 
);

创建索引的时候要根据使用的算法:

-- 创建索引
CREATE INDEX ON test USING ivfflat ( field3);
CREATE INDEX ON test USING ivfflat ( field3 vector_ip_ops) WITH (lists = 50);
CREATE INDEX ON test USING ivfflat ( field3 vector_ip_ops) WITH (lists = 500);
CREATE INDEX ON test USING ivfflat ( field3 vector_ip_ops) WITH (lists = 1024);

这里提供一个mapper文件内SQL的书写方法【查询相似度排名前十】:

<select id="queryId" resultType="map">
        SELECT
        field1,
        field2,
        field3 <![CDATA[ <#> ]]> CAST ( #{featrue}  AS vector ) AS "score"
        FROM test
        ORDER BY field1 <![CDATA[ <#> ]]> CAST ( #{featrue}  AS vector )
        LIMIT 10;
    </select>

符号说明:

  1. L2 Distance(<->):L2 距离,也称为欧氏距离或欧几里得距离,用于度量两个向量之间的直线距离。L2 距离的计算方法是将两个向量的对应元素差的平方相加,然后取平方根。L2 距离较小表示向量之间更接近。
  2. Inner Product(<#>):内积距离,也称为余弦距离或内积相似度,用于度量两个向量之间的夹角余弦值。内积距离的计算方法是两个向量的点积除以两个向量的范数的乘积。内积距离越大表示向量之间的夹角越小,相似度越高。
  3. Cosine Distance(<=>):余弦距离,也称为余弦相似度的补数。余弦距离是一种度量两个向量之间夹角的距离指标,取值范围从 0 到 2,其中 0 表示完全相似,2 表示完全不相似。余弦距离的计算方法是两个向量的点积除以两个向量的范数的乘积的补数。

性能测试如下:

PostgreSQL.vector.search cost [30]

3.总结

各有优势:Milvus无需重建索引,查询速度较快;Vector不用专门部署,好维护。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
3月前
|
存储 安全 C++
Odoo 安装方式选择:源码安装 vs Docker
Odoo部署常采用源码编译或Docker容器化,但分别面临依赖复杂、版本风险和服务化难题,以及镜像臃肿和扩展受限的问题。Websoft9提出混合方案,融合两者优势:通过智能环境适配、三阶段部署流程(环境预检、混合模式选择、持久化配置)及声明式YAML配置,实现高效、灵活的双模运行时。此方案显著降低依赖冲突解决时间(从83分钟至0),生产环境构建耗时缩短至8分钟,并达100% CVE漏洞修复率,适合ERP定制开发与规模化部署的企业需求。
|
1月前
|
存储 Ubuntu Docker
Ubuntu 安装 docker
本文介绍了在 Ubuntu 系统上安装 Docker 的详细步骤,包括卸载旧版本、设置 Docker 官方存储库、安装 Docker 包以及配置镜像源加速。首先通过移除旧版组件如 `docker.io` 和 `docker-compose` 等进行清理,然后添加官方 GPG 密钥并配置 APT 源,接着安装最新 Docker 组件。此外,还提供了阿里云和 1Panel 的镜像源配置方法以提升下载速度,并通过运行 `hello-world` 镜像测试安装是否成功。
859 3
Ubuntu 安装 docker
|
3月前
|
监控 Java Go
无感改造,完美监控:Docker 多阶段构建 Go 应用无侵入观测
本文将介绍一种基于 Docker 多阶段构建的无侵入 Golang 应用观测方法,通过此方法用户无需对 Golang 应用源代码或者编译指令做任何改造,即可零成本为 Golang 应用注入可观测能力。
238 85
|
1月前
|
Linux iOS开发 Docker
MyEMS开源系统安装之Linux/macOS上的DOcker
本指南详细介绍了如何在Linux/macOS上使用Docker部署MyEMS系统。主要内容包括:前置条件(如安装Docker、npm和MySQL),以及分步骤部署各个组件(如myems-api、myems-admin、myems-modbus-tcp等)。每个步骤涵盖源代码复制、环境配置、镜像构建、容器运行及日志管理等操作,并提供了多平台构建的支持。最后,指南还说明了默认端口和登录凭据,帮助用户快速启动并访问MyEMS的管理界面和Web界面。
69 1
|
2月前
|
关系型数据库 MySQL 数据库
Docker 安装常用软件相关命令
本文介绍了在CentOS 7.9系统上安装Docker的详细步骤,包括添加阿里云镜像源、安装Docker及相关组件、启动服务以及配置镜像加速。同时,还展示了如何通过Docker安装MySQL 5.7版本数据库,涵盖拉取镜像、创建数据目录、运行容器及配置挂载点等操作,并提供验证安装成功的命令和截图。适合需要部署Docker与MySQL环境的用户参考。
207 5
|
2月前
|
存储 弹性计算 Linux
安装Docker
常见操作系统安装docker步骤
187 15
|
2月前
|
Docker 容器
在openEuler 22.03 LTS上安装Docker CE和Docker Compose
以上就是在openEuler 22.03 LTS上安装Docker CE和Docker Compose的过程。希望这个指南能帮助你顺利完成安装。
437 12
|
3月前
|
Linux 虚拟化 Docker
win11怎么安装docker的必要设置自学软硬件工程师778天
win11怎么安装docker的必要设置自学软硬件工程师778天
win11怎么安装docker的必要设置自学软硬件工程师778天
|
3月前
|
Prometheus 监控 Cloud Native
Prometheus+Grafana(docker安装)
本文档详细介绍了如何使用Docker容器快速部署Prometheus监控系统和Grafana数据可视化平台。该方案适用于需要快速搭建监控环境的开发测试场景,具备部署简单、资源占用低、易于维护等特点。
|
3月前
|
Ubuntu 关系型数据库 MySQL
在Ubuntu系统的Docker上安装MySQL的方法
以上的步骤就是在Ubuntu系统的Docker上安装MySQL的详细方法,希望对你有所帮助!
361 12