日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

pgvector兼容模式使用指南

pgvector是基于PostgreSQL數(shù)據(jù)庫的開源向量化數(shù)據(jù)的工具包。使用pgvector可以方便地構(gòu)建向量索引,執(zhí)行向量之間的相似度計算和查詢,常用于向量相似度搜索、推薦系統(tǒng)、聚類分析等場景。

前提條件

使用pgvector兼容模式前,請先滿足以下條件:

pgvector兼容模式說明

對于使用pgvector做向量檢索引擎的業(yè)務(wù),云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫對pgvector的向量讀寫操作可以完全兼容,只需要修改索引構(gòu)建的SQL語法即可。因此使用pgvector做向量檢索的業(yè)務(wù)可以完全無縫遷移到云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫中,基本不需要對業(yè)務(wù)側(cè)的代碼做改動。相比于原生的pgvector向量檢索引擎,云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫的pgvector兼容模式具有以下優(yōu)勢:

  • 基本上完全兼容pgvector的SQL語法,可以完全復(fù)用pgvector生態(tài)的客戶端。

  • pgvector目前主要在單機PostgreSQL數(shù)據(jù)庫上使用,而云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫是分布式版,能處理更大的向量數(shù)據(jù)量。

  • 云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫使用自研的FastANN向量檢索引擎,具備比原生pgvector更優(yōu)秀的性能,詳情請查看向量分析性能測試

  • 同時云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫在優(yōu)化器和執(zhí)行器層面打通了混合查詢計劃生成與混合查詢執(zhí)行算子,具備非常完備的混合查詢能力,而原生pgvector基本不具備混合查詢的能力(只能通過分區(qū)等手段實現(xiàn)簡單的場景)。

  • 云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫擁有Float2類型,可以對向量表存儲進行壓縮;也具備PQ量化能力,可以對向量索引存儲進行壓縮。因此云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫相比于原生pgvector,也具有存儲成本的優(yōu)勢。

創(chuàng)建向量表

創(chuàng)建兼容pgvector語法的向量表和云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版中原生向量表的語法相同,只是表中的向量列由數(shù)組(smallint[]float2[]float4[])類型改為了vector類型(pgvector定義的向量類型),并且一個表可以支持多個向量列。

語法

CREATE TABLE [TABLE_NAME]
(  
    C1 DATATYPE,  
    C2 DATATYPE,  
    ......,  
    CN VECTOR(DIM), 
    PRIMARY KEY(C1 [,C2,...CN])
) DISTRIBUTED BY(C1);

其中CN為向量列,為vector類型,參數(shù)DIM為向量的維度。

示例

創(chuàng)建一個命名為FACE_TABLE的向量表,其中C1為主鍵,C2和C3均為向量列,具體示例如下:

CREATE TABLE FACE_TABLE (  
    C1 INT,  
    C2 VECTOR(512) NOT NULL, 
    C3 VECTOR(1536) NOT NULL, 
    C4 TIMESTAMP NOT NULL,  
    C5 VARCHAR(20) NOT NULL,  
    PRIMARY KEY (C1)
) DISTRIBUTED BY (C1);

創(chuàng)建向量索引

云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫的pgvector兼容模式下向量索引的創(chuàng)建語法,仍然采用FastANN向量檢索引擎的語法,與pgvector的原生語法規(guī)則不同,具體可以參考如下所示語法:

語法

CREATE INDEX [INDEX_NAME]
ON [SCHEMA_NAME].[TABLE_NAME]   
USING ANN(COLUMN_NAME) 
WITH (DIM=<DIMENSION>,
      DISTANCEMEASURE=<MEASURE>,
      HNSW_M=<M>,
      HNSW_EF_CONSTRUCTION=<EF_CONSTURCTION>,
      PQ_ENABLE=<PQ_ENABLE>,
      PQ_SEGMENTS=<PQ_SEGMENTS>,
      PQ_CENTERS=<PQ_CENTERS>,
      EXTERNAL_STORAGE=<EXTERNAL_STORAGE>;

由于pgvector的vector類型已經(jīng)包含了維度信息,創(chuàng)建索引中的DIM可以不填,其他參數(shù)可以查看原生向量索引的語法創(chuàng)建規(guī)則,詳情請參見創(chuàng)建向量索引

示例

在上文的FACE_TABLE的向量表上繼續(xù)創(chuàng)建索引,具體示例如下:

-- 在向量列C2上創(chuàng)建三種向量索引。
CREATE INDEX idx_c2_l2 ON FACE_TABLE USING ann(C2) WITH (distancemeasure=l2, hnsw_m=64, pq_enable=1);
CREATE INDEX idx_c2_ip ON FACE_TABLE USING ann(C2) WITH (distancemeasure=ip, hnsw_m=64, pq_enable=1);
CREATE INDEX idx_c2_cosine ON FACE_TABLE USING ann(C2) WITH (distancemeasure=cosine, hnsw_m=64, pq_enable=1);
-- 在向量列C3上創(chuàng)建三種向量索引。
CREATE INDEX idx_c3_l2 ON FACE_TABLE USING ann(C3) WITH (distancemeasure=l2, hnsw_m=64, pq_enable=1);
CREATE INDEX idx_c3_ip ON FACE_TABLE USING ann(C3) WITH (distancemeasure=ip, hnsw_m=64, pq_enable=1);
CREATE INDEX idx_c3_cosine ON FACE_TABLE USING ann(C3) WITH (distancemeasure=cosine, hnsw_m=64, pq_enable=1);

該示例中列舉了在多個向量列上創(chuàng)建多個向量索引,在實際使用過程中需根據(jù)實際使用情況進行創(chuàng)建,以避免創(chuàng)建無效索引。

向量數(shù)據(jù)導(dǎo)入

兼容pgvector語法的向量表的向量數(shù)據(jù)導(dǎo)入完全兼容pgvector的語法。以上文的FACE_TABLE表為例說明INSERT的使用方法,具體示例如下:

INSERT INTO FACE_TABLE 
values (1, '[1,2,3 ... 512]', '[1,2,3 ... 1536]', '2023-12-29 00:00:00', 'aaa.bbb.ccc/face1.jpg');

向量檢索

對于使用pgvector語法的向量表,向量檢索的語法和pgvector原生語法完全兼容,可以直接使用pgvector的原生查詢方式進行查詢。

與向量檢索召回率相關(guān)的內(nèi)核參數(shù)與云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫的原生參數(shù)一致,詳情請參見向量檢索。以FACE_TABLE為例說明向量檢查的具體使用方式:

-- 精確搜索方式:按歐氏距離排序。
SELECT C1 FROM FACE_TABLE ORDER BY vector_l2_squared_distance(C2, '[1,2,3 ... 512]') LIMIT 10;
-- 精確搜索方式:按內(nèi)積距離排序。
SELECT C1 FROM FACE_TABLE ORDER BY vector_negative_inner_product(C2, '[1,2,3 ... 512]') LIMIT 10;
-- 精確搜索方式:按余弦相似度排序。
SELECT C1 FROM FACE_TABLE ORDER BY cosine_distance(C2, '[1,2,3 ... 512]') LIMIT 10;

-- 近似搜索方式:按歐氏距離排序。
SELECT C1 FROM FACE_TABLE ORDER BY C2 <-> '[1,2,3 ... 512]' LIMIT 10;
-- 近似搜索方式:按內(nèi)積距離排序。
SELECT C1 FROM FACE_TABLE ORDER BY C2 <#> '[1,2,3 ... 512]' LIMIT 10;
-- 近似搜索方式:按余弦相似度排序。
SELECT C1 FROM FACE_TABLE ORDER BY C2 <=> '[1,2,3 ... 512]' LIMIT 10;

由于已經(jīng)在FACE_TABLE表的C2列上建了歐氏距離,內(nèi)積距離和余弦相似度三種距離度量的索引,因此示例中的三種近似搜索方式均能命中對應(yīng)的向量索引。在實際使用的過程中,需要注意近似查詢方式中的操作符<-><#><=>必須與向量索引的距離度量一一對應(yīng),否則如果沒有對應(yīng)的距離度量的索引,將會退化為精確搜索。

向量檢索的SQL優(yōu)化

  • 當(dāng)需要返回向量的距離score,您可以使用下面的SQL來提升性能。直接在向量索引的排序值基礎(chǔ)上進行計算得到最終的score,可以節(jié)省大量的計算耗時,具體示例如下:

    -- 按歐氏距離排序的向量檢索。
    SELECT t.C1 as C1, sqrt(t.score) as score 
    FROM 
      (SELECT C1,C2 <-> '[1,2,3 ... 512]' as score
       FROM FACE_TABLE
       ORDER BY score LIMIT topk) t;
    
    -- 按內(nèi)積距離排序的向量檢索。
    SELECT t.C1 as C1, (-1 * t.score) as score
    FROM
      (SELECT C1, C2 <#> '[1,2,3 ... 512]' as score
       FROM FACE_TABLE
       ORDER BY score LIMIT topk) t;
    
    -- 按余弦相似度排序的向量檢索。
    SELECT t.C1 as C1, (1.0 - t.score) as score
    FROM 
      (SELECT C1, C2 <=> '[1,2,3 ... 512]' as score
       FROM FACE_TABLE
       ORDER BY score LIMIT topk) t;

    向量檢索返回的結(jié)果中,score分別為歐氏距離(開方值),內(nèi)積距離和余弦相似度。

  • 當(dāng)需要根據(jù)score的范圍進行過濾并返回結(jié)果,您可以使用下面的SQL來實現(xiàn)。利用向量索引的排序值進行計算得到最終的score,可以節(jié)省大量的計算耗時,具體示例如下:

    -- 按歐氏距離排序的向量檢索。
    SELECT t.C1 as C1, sqrt(t.score) as score 
    FROM 
      (SELECT C1,C2 <-> '[1,2,3 ... 512]' as score
       FROM FACE_TABLE
       ORDER BY score LIMIT topk) t
    WHERE score < 100;
    
    -- 按內(nèi)積距離排序的向量檢索。
    SELECT t.C1 as C1, (-1 * t.score) as score
    FROM
      (SELECT C1, C2 <#> '[1,2,3 ... 512]' as score
       FROM FACE_TABLE
       ORDER BY score LIMIT topk) t
    WHERE score > 10;
    
    -- 按余弦相似度排序的向量檢索。
    SELECT t.C1 as id, (1.0 - t.score) as score
    FROM 
      (SELECT C1, C2 <=> '[1,2,3 ... 512]' as score
       FROM FACE_TABLE
       ORDER BY score LIMIT topk) t
    WHERE score > 0.5;

混合查詢

對于使用pgvector語法的向量表,混合查詢的方式與云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫的原生語法完全一致,詳情請參見混合檢索使用指南。下文以FACE_TABLE舉例說明混合查詢使用方法。

SELECT C1 FROM FACE_TABLE WHERE
  C4 > '2023-10-01 00:00:00' AND C4 < '2024-01-01 00:00:00'
ORDER BY 
  C2 <-> '[1,2,3 ... 512]'
LIMIT 10;

開源代碼庫適配

以開源大模型應(yīng)用研發(fā)平臺DIFY為例,介紹如何通過簡單的改造,讓使用pgvector的業(yè)務(wù)應(yīng)用代碼能快速適配云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫。主要涉及三個方面的修改:

  • 去除pgvector的插件安裝。由于云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫并沒有適配pgvector插件,只是在語法上兼容了pgvector的向量表讀寫,因此不需要安裝pgvector的插件。云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫在開通時會默認安裝自研向量檢索引擎插件FastANN,只需要去掉pgvector的插件即可。具體示例代碼如下:

    # 代碼位于api/core/rag/datasource/vdb/pgvector/pgvector.py
    
    def _create_collection(self, dimension: int):
        cache_key = f"vector_indexing_{self._collection_name}"
        lock_name = f"{cache_key}_lock"
        WITH redis_client.lock(lock_name, timeout=20):
            collection_exist_cache_key = f"vector_indexing_{self._collection_name}"
            if redis_client.get(collection_exist_cache_key):
                RETURN
    
            WITH self._get_cursor() AS cur:
                # 去除下面的pgvector插件安裝
                #cur.execute("CREATE EXTENSION IF NOT EXISTS vector")
                cur.execute(SQL_CREATE_TABLE.format(table_name=self.table_name, dimension=dimension))
                # TODO: CREATE index https://github.com/pgvector/pgvector?tab=readme-ov-file#indexing
            redis_client.set(collection_exist_cache_key, 1, ex=3600)
        
  • 修改向量表創(chuàng)建。由于云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫是基于PostgreSQL9.4版本,不支持建表時使用using heap語法。云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版屬于分布式數(shù)據(jù)庫,需要設(shè)置分布鍵。修改向量表創(chuàng)建語句示例代碼如下:

    # 代碼位于api/core/rag/datasource/vdb/pgvector/pgvector.py
    
    SQL_CREATE_TABLE = """
    CREATE TABLE IF NOT EXISTS {table_name} (
        id uuid PRIMARY KEY,
        text text NOT NULL,
        meta jsonb NOT NULL,
        embedding vector({dimension}) NOT NULL
    ) USING heap; 
    """
    
    # 修改為如下代碼:
    
    SQL_CREATE_TABLE = """
    CREATE TABLE IF NOT EXISTS {table_name} (
        id uuid PRIMARY KEY,
        text text NOT NULL,
        meta jsonb NOT NULL,
        embedding vector({dimension}) NOT NULL
    ) DISTRIBUTED BY (id); 
    """
  • 修改向量索引創(chuàng)建。由于云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫采用的是自研向量檢索引擎FastANN的向量能力,并不是直接移植的pgvector插件,在向量索引的創(chuàng)建語法上是有區(qū)別的,尤其是索引關(guān)鍵詞是不同的。因此必須按照云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫的語法進行索引的創(chuàng)建。具體示例代碼如下:

    # 代碼位于api/core/rag/datasource/vdb/pgvector/pgvector.py
    
    # 添加創(chuàng)建向量索引的SQL(也可以直接在數(shù)據(jù)庫上創(chuàng)建索引,不再此添加)
    
    SQL_CREATE_INDEX = """
    CREATE INDEX ON  {table_name} USING ann(embedding) WITH (HNSW_M=16, HNSW_EF_CONSTRUCTION=500, PQ_ENABLE=1);
    """
    
    def _create_collection(self, dimension: int):
        cache_key = f"vector_indexing_{self._collection_name}"
        lock_name = f"{cache_key}_lock"
        WITH redis_client.lock(lock_name, timeout=20):
            collection_exist_cache_key = f"vector_indexing_{self._collection_name}"
            if redis_client.get(collection_exist_cache_key):
                RETURN
    
            WITH self._get_cursor() AS cur:
                # 去除下面的pgvector插件安裝
                #cur.execute("CREATE EXTENSION IF NOT EXISTS vector")
                cur.execute(SQL_CREATE_TABLE.format(table_name=self.table_name, dimension=dimension))
                # TODO: CREATE index https://github.com/pgvector/pgvector?tab=readme-ov-file#indexing
                # 創(chuàng)建ADB-PG向量數(shù)據(jù)庫的向量索引
                cur.execute(SQL_CREATE_INDEX.format(table_name=self.table_name))
            redis_client.set(collection_exist_cache_key, 1, ex=3600)

相關(guān)參考

pgvector多種語言的客戶端

語言

客戶端庫代碼地址

C

pgvector-C

C++

pgvector-cpp

Go

pgvector-go

Java,Kotlin,Groovy,Scala

pgvector-java

PHP

pgvector-php

Python

pgvector-python

Rust

pgvector-rust

pgvector生態(tài)的多種語言的客戶端均可以無縫接入到云原生數(shù)據(jù)倉庫AnalyticDB PostgreSQL版向量數(shù)據(jù)庫,只需對向量索引相關(guān)的SQL進行修改即可。

支持的向量函數(shù)

函數(shù)作用

向量函數(shù)

返回值類型

含義

支持的數(shù)據(jù)類型

計算

l2_distance

double precision

歐氏距離(開方值),通常用于衡量兩個向量的大小,表示兩個向量的距離。

vector

inner_product

double precision

內(nèi)積距離,在向量歸一化之后等于余弦相似度,通常用于在向量歸一化之后替代余弦相似度。

vector

cosine_similarity

double precision

余弦相似度,取值范圍:[-1, 1],通常用于衡量兩個向量在方向上的相似性,而不關(guān)心兩個向量的實際長度。

vector

vector_dims

integer

計算單個向量的維度。

vector

vector_norm

double precision

計算單個向量的模長。

vector

vector_add

vector

兩個向量做加法。

vector

vector_sub

vector

兩個向量做減法。

vector

vector_mul

vector

兩個向量做乘法。

vector

vector_angle

double precision

計算兩個向量的夾角。

vector

排序

vector_l2_squared_distance

double precision

歐氏距離(平方值),由于比歐氏距離(開方值)少了開方的計算,因此主要用于對歐氏距離(開方值)的排序邏輯,以減少計算量。

vector

vector_negative_inner_product

double precision

反內(nèi)積距離,為內(nèi)積距離取反后的結(jié)果,主要用于對內(nèi)積距離的排序邏輯,以保證排序結(jié)果按內(nèi)積距離從大到小排序。

vector

cosine_distance

double precision

余弦距離,取值范圍:[0, 2],主要用于對余弦相似度的排序邏輯,以保證排序結(jié)果按余弦相似度從大到小排序。

vector

表格中向量距離的計算公式詳情,請參見創(chuàng)建向量索引

向量函數(shù)的使用示例:

-- 歐氏距離
SELECT l2_distance('[1,1,1,1]'::vector, '[2,2,2,2]'::vector);
-- 內(nèi)積距離
SELECT inner_product('[1,1,1,1]'::vector, '[2,2,2,2]'::vector);
-- 余弦相似度
SELECT cosine_similarity('[1,1,1,1]'::vector, '[2,2,2,2]'::vector);
-- 向量維度
SELECT vector_dims('[1,1,1,1]'::vector);
-- 向量模長
SELECT vector_norm('[1,1,1,1]'::vector);
-- 向量加法
SELECT vector_add('[1,1,1,1]'::vector, '[2,2,2,2]'::vector);
-- 向量減法
SELECT vector_sub('[1,1,1,1]'::vector, '[2,2,2,2]'::vector);
-- 向量乘法
SELECT vector_mul('[1,1,1,1]'::vector, '[2,2,2,2]'::vector);
-- 向量夾角
SELECT vector_angle('[1,1,1,1]'::vector, '[2,2,2,2]'::vector);
-- 歐氏平方距離
SELECT vector_l2_squared_distance('[1,1,1,1]'::vector, '[2,2,2,2]'::vector);
-- 反內(nèi)積距離
SELECT vector_negative_inner_product('[1,1,1,1]'::vector, '[2,2,2,2]'::vector);
-- 余弦距離
SELECT cosine_distance('[1,1,1,1]'::vector, '[2,2,2,2]'::vector);

支持的向量操作符

操作符

計算含義

排序含義

支持的數(shù)據(jù)類型

<->

獲取歐氏距離(平方),結(jié)果等同于l2_squared_distance。

按歐氏距離(平方)從小到大排序。

vector

<#>

獲取反內(nèi)積,結(jié)果等同于negative_inner_product_distance。

按點積距離從大到小排序。

vector

<=>

獲取余弦距離,結(jié)果等同于cosine_distance。

按余弦相似度從大到小排序。

vector

+

兩個向量的加法

vector

-

兩個向量的減法

vector

*

兩個向量的乘法

vector

向量操作符的使用示例:

-- 歐氏距離(平方)
SELECT '[1,1,1,1]'::vector <-> '[2,2,2,2]'::vector AS score;
 
-- 反內(nèi)積距離
SELECT '[1,1,1,1]'::vector <#> '[2,2,2,2]'::vector AS score;
 
-- 余弦距離
SELECT '[1,1,1,1]'::vector <=> '[2,2,2,2]'::vector AS score;

-- 加法
SELECT '[1,1,1,1]'::vector + '[2,2,2,2]'::vector AS value;

-- 減法
SELECT '[1,1,1,1]'::vector - '[2,2,2,2]'::vector AS value;

-- 乘法
SELECT '[1,1,1,1]'::vector * '[2,2,2,2]'::vector AS value;