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

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 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数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
1月前
|
关系型数据库 分布式数据库 数据库
PolarDB常见问题之加了索引但是查询没有使用如何解决
PolarDB是阿里云推出的下一代关系型数据库,具有高性能、高可用性和弹性伸缩能力,适用于大规模数据处理场景。本汇总囊括了PolarDB使用中用户可能遭遇的一系列常见问题及解答,旨在为数据库管理员和开发者提供全面的问题指导,确保数据库平稳运行和优化使用体验。
|
18天前
|
Docker 容器 关系型数据库
【PolarDB-X从入门到精通】 第四讲:PolarDB分布式版安装部署(源码编译部署)
本期课程将于4月11日19:00开始直播,内容包括源码编译基础知识和实践操作,课程目标是使学员掌握源码编译部署技能,为未来发展奠定基础,期待大家在课程中取得丰富的学习成果!
【PolarDB-X从入门到精通】 第四讲:PolarDB分布式版安装部署(源码编译部署)
|
10天前
|
SQL 存储 Oracle
关系型数据库查询数据的语句
本文介绍了关系型数据库中的基本SQL查询语句,包括选择所有或特定列、带条件查询、排序、分组、过滤分组、表连接、限制记录数及子查询。SQL还支持窗口函数、存储过程等高级功能,是高效管理数据库的关键。建议深入学习SQL及相应数据库系统文档。
9 2
|
17天前
|
关系型数据库 PostgreSQL
postgresql安装
postgresql安装
36 8
|
1月前
|
SQL 关系型数据库 分布式数据库
PolarDB常见问题之安装postgis报错如何解决
PolarDB是阿里云推出的下一代关系型数据库,具有高性能、高可用性和弹性伸缩能力,适用于大规模数据处理场景。本汇总囊括了PolarDB使用中用户可能遭遇的一系列常见问题及解答,旨在为数据库管理员和开发者提供全面的问题指导,确保数据库平稳运行和优化使用体验。
|
1月前
|
关系型数据库 分布式数据库 PolarDB
PolarDB常见问题之安装gms时出现docker如何解决
PolarDB是阿里云推出的下一代关系型数据库,具有高性能、高可用性和弹性伸缩能力,适用于大规模数据处理场景。本汇总囊括了PolarDB使用中用户可能遭遇的一系列常见问题及解答,旨在为数据库管理员和开发者提供全面的问题指导,确保数据库平稳运行和优化使用体验。
|
1月前
|
SQL 关系型数据库 分布式数据库
PolarDB常见问题之PolarDB-X部署三台失败如何解决
PolarDB是阿里云推出的下一代关系型数据库,具有高性能、高可用性和弹性伸缩能力,适用于大规模数据处理场景。本汇总囊括了PolarDB使用中用户可能遭遇的一系列常见问题及解答,旨在为数据库管理员和开发者提供全面的问题指导,确保数据库平稳运行和优化使用体验。
|
1月前
|
存储 Kubernetes 分布式数据库
利用Helm在K8S上部署 PolarDB-X 集群(详细步骤--亲测!!!)
利用Helm在K8S上部署 PolarDB-X 集群(详细步骤--亲测!!!)
93 0
|
2月前
|
关系型数据库 数据库 PostgreSQL
Docker安装postgreSql
Docker安装postgreSql步骤
|
2月前
|
容器
为什么在部署PolarDB-X时会卡在这了不动
【2月更文挑战第2天】为什么在部署PolarDB-X时会卡在这了不动
19 3