自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何使用Postgres DB實(shí)現(xiàn)混合搜索

譯文 精選
數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù)
本文解釋了如何在單個(gè)PostgresDB中使用全文搜索和pgvector實(shí)現(xiàn)混合搜索(詞法和語(yǔ)義)。

譯者 | 布加迪

審校 | 重樓

使用傳統(tǒng)的基于詞匯(或基于關(guān)鍵字)的搜索,我們可以找到含我們搜索的確切單詞的文檔。關(guān)鍵詞搜索在準(zhǔn)確性方面表現(xiàn)出色,但在替代詞語(yǔ)或自然語(yǔ)言方面表現(xiàn)差強(qiáng)人意。

語(yǔ)義搜索通過(guò)捕獲文檔和用戶查詢背后的意圖來(lái)克服這些限制。這通常通過(guò)利用向量嵌入將文檔和查詢映射到高維空間,并計(jì)算向量相似性以檢索相關(guān)結(jié)果來(lái)實(shí)現(xiàn)。

針對(duì)幾種系統(tǒng),單一的搜索方法可能會(huì)失敗,導(dǎo)致向用戶顯示不完整的信息。結(jié)合上述兩種搜索方法的優(yōu)勢(shì)將使我們能夠提供出色的搜索體驗(yàn)。

Elasticsearch和Apache Solr等系統(tǒng)都很好地支持基于關(guān)鍵字的搜索。語(yǔ)義搜索通常需要使用向量數(shù)據(jù)庫(kù)進(jìn)行存儲(chǔ),市面上有多種解決方案。這篇文章解釋了我們?nèi)绾卧赑ostgres中使用單單一個(gè)熟悉的存儲(chǔ)系統(tǒng)來(lái)支持包括詞匯搜索和語(yǔ)義搜索的混合搜索。

假設(shè)我們有一個(gè)應(yīng)用程序使用下面的表,允許用戶通過(guò)關(guān)鍵字或自然語(yǔ)言搜索產(chǎn)品:

SQL
CREATE TABLE products (

id bigserial PRIMARY KEY,

description VARCHAR(255),

embedding vector(384)

);

description列包含產(chǎn)品的文本/自然語(yǔ)言描述。Postgres在該列上為全文搜索提供了默認(rèn)索引,但是我們也可以創(chuàng)建自定義索引加速全文搜索,作用類(lèi)似信息檢索的索引。

embedding列存儲(chǔ)產(chǎn)品描述的向量(浮點(diǎn))表示,捕獲語(yǔ)義含義而不是單詞。Postgres中的pgvector擴(kuò)展帶來(lái)了向量數(shù)據(jù)類(lèi)型和向量相似性度量指標(biāo):L2、余弦和點(diǎn)積距離。有幾種方法可以生成嵌入,比如使用詞級(jí)嵌入(如Word2Vec、句子/文檔嵌入(如SBERT)或者來(lái)自基于Transformer的模型(如BERT模型)的嵌入。

為了演示,我們將在數(shù)據(jù)庫(kù)中插入以下數(shù)據(jù):

SQL
INSERT INTO products (description) VALUES

 ('Organic Cotton Baby Onesie - Newborn Size, Blue'), 

 ('Soft Crib Sheet for Newborn, Hypoallergenic'), 

('Baby Monitor with Night Vision and Two-Way Audio'),

('Diaper Bag Backpack with Changing Pad - Unisex Design'),
 ('Stroller for Infants and Toddlers, Lightweight'),

 ('Car Seat for Newborn, Rear-Facing, Extra Safe'),

 ('Baby Food Maker, Steamer and Blender Combo'),

 ('Toddler Sippy Cup, Spill-Proof, BPA-Free'),

 ('Educational Toys for 6-Month-Old Baby, Colorful Blocks'),

 ('Baby Clothes Set - 3 Pack, Cotton, 0-3 Months'),

('High Chair for Baby, Adjustable Height, Easy to Clean'),

('Baby Carrier Wrap, Ergonomic Design for Newborns'),

 ('Nursing Pillow for Breastfeeding, Machine Washable Cover'),

 ('Baby Bath Tub, Non-Slip, for Newborn and Infant'), 

 ('Baby Skincare Products - Lotion, Shampoo, Wash - Organic');

針對(duì)嵌入,我使用了SentenceTransformer模型(又名SBERT生成嵌入,然后將它們存儲(chǔ)在數(shù)據(jù)庫(kù)中。下面的Python代碼演示了這一點(diǎn):

SQL
descriptions = [product[1] for product in products]
model = SentenceTransformer("all-MiniLM-L6-v2")
embeddings = model.encode(descriptions)

# Update the database with embeddings
for i, product in enumerate(products):
product_id = product[0]
embedding = embeddings[i] # Convert to Python list

# Construct the vector string representation
embedding_str = str(embedding.tolist())
cur.execute("UPDATE products SET embedding = %s WHERE id = %s", (embedding_str, product_id))

# Commit changes and close connection
conn.commit()

全文搜索

Postgres為關(guān)鍵字搜索提供了廣泛的開(kāi)箱即用支持。我們可以為基于關(guān)鍵字的檢索編寫(xiě)如下查詢:

假設(shè)我們想要搜索嬰兒睡眠用品。我們可以使用以下查詢進(jìn)行搜索:

SQL
SELECT id, description
FROM products
WHERE description @@ to_tsquery('english', 'crib | baby | bed');

這將返回以下產(chǎn)品:

SQL
"Soft Crib Sheet for Newborn, Hypoallergenic"

注意:ts_query搜索詞素/標(biāo)準(zhǔn)化關(guān)鍵字,因此用newbornsbabies替換newborn也會(huì)返回相同的結(jié)果。

當(dāng)然,上面只是一個(gè)簡(jiǎn)單的例子,Postgres的全文搜索功能允許我們進(jìn)行一定制,比如跳過(guò)某些單詞、處理同義詞、使用復(fù)雜的解析等,通過(guò)覆蓋默認(rèn)的文本搜索配置來(lái)實(shí)現(xiàn)。

雖然這些查詢?cè)跊](méi)有索引的情況下也可以工作,但大多數(shù)應(yīng)用程序發(fā)現(xiàn)這種方法太慢了,可能除了偶爾的臨時(shí)搜索之外。文本搜索的實(shí)際應(yīng)用通常需要?jiǎng)?chuàng)建索引。下面的代碼演示了如何針對(duì)description列創(chuàng)建GIN索引(廣義倒排索引),并使用它進(jìn)行高效搜索。

SQL
--Create a tsvector column (you can add this to your existing table) 

ALTER TABLE products ADD COLUMN description_tsv tsvector;

 --Update the tsvector column with indexed data from the description column 

UPDATE products SET description_tsv = to_tsvector('english', description); 

-- Create a GIN index on the tsvector column 

CREATE INDEX idx_products_description_tsv ON products USING gin(description_tsv);

語(yǔ)義搜索示例

現(xiàn)在不妨嘗試為我們的查詢意圖(“嬰兒睡眠用品”)執(zhí)行語(yǔ)義搜索請(qǐng)求。為,我們計(jì)算嵌入(如上所述),并根據(jù)向量距離(在本例中為余弦距離)選擇最相似的產(chǎn)品。下面的代碼演示了這一點(diǎn):

Python
# The query string
query_string = 'baby sleeping accessories'

# Generate embedding for the query string
query_embedding = model.encode(query_string).tolist()

# Construct the SQL query using the cosine similarity operator (<->)
# Assuming you have an index that supports cosine similarity (e.g., ivfflat with vector_cosine_ops)
sql_query = """
SELECT id, description, (embedding <-> %s::vector) as similarity
FROM products
ORDER BY similarity
LIMIT 5;
"""

# Execute the query
cur.execute(sql_query, (query_embedding,))

# Fetch and print the results
results = cur.fetchall()
for result in results:
product_id, description, similarity = result
print(f"ID: {product_id}, Description: {description}, Similarity: {similarity}")

cur.close()
conn.close()

這給了我們以下結(jié)果:

Plain Text
ID: 12, Description: Baby Carrier Wrap, Ergonomic Design for Newborns, Similarity: 0.9956936200879117
ID: 2, Description: Soft Crib Sheet for Newborn, Hypoallergenic, Similarity: 1.0233573590998544
ID: 5, Description: Stroller for Infants and Toddlers, Lightweight, Similarity: 1.078171715208051
ID: 6, Description: Car Seat for Newborn, Rear-Facing, Extra Safe, Similarity: 1.08259154868697
ID: 3, Description: Baby Monitor with Night Vision and Two-Way Audio, Similarity: 1.0902734271784085

除了每個(gè)結(jié)果,我們還返回了相似性(余弦相似性而言越低越好)。正如我們所見(jiàn),通過(guò)嵌入搜索,我們得到了更豐富的結(jié)果集,這很好地補(bǔ)充了基于關(guān)鍵字的搜索。

默認(rèn)情況下,pgvector執(zhí)行精確的最近鄰搜索,保證完美的召回。然而,隨著數(shù)據(jù)集大小增加,這種方法的成本相當(dāng)高。我們可以添加一個(gè)索引,召回換取速度。一個(gè)例子是Postgres中的IVFFlat(倒置文件與平面壓縮)索引,其工作原理是,使用k-means聚類(lèi)將向量空間劃分為簇類(lèi)。在搜索期間,它識(shí)別最接近查詢向量的簇類(lèi),并在這些選定的簇類(lèi)中執(zhí)行線性掃描,計(jì)算查詢向量與這些簇類(lèi)中向量之間的精確距離。下面的代碼定義了如何創(chuàng)建這樣一個(gè)索引:

SQL
CREATE INDEX ON products USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100); 

lists indicates the number of clusters to create.
vector_cosine_ops indicates the distance metric we are using (cosine, inner product, or Euclidean/L2)

結(jié)果融合

上述兩種方法在不同的場(chǎng)景中表現(xiàn)出色,并相輔相成。將兩種方法的結(jié)果結(jié)合起來(lái)有望得到穩(wěn)健的搜索結(jié)果。倒數(shù)排序融合(RRF)是一種將多個(gè)具有不同相關(guān)指標(biāo)的結(jié)果集組合成單個(gè)結(jié)果集的方法。RRF不需要調(diào)優(yōu),不同的相關(guān)指標(biāo)也沒(méi)必要相互關(guān)聯(lián)才能獲得高質(zhì)量的結(jié)果。RRF的核心體現(xiàn)在其公式中:

Mathematica

RRF(d) = (r R) 1 / k + r(d))

其中

- d 是文檔

- R 是排序器(檢索器)集

- k 是常數(shù)(通常是60

- r(d) 是排序器(r)中的文檔(d)排序

在我們的例子中,我們將這樣做:

1. 通過(guò)在添加一個(gè)常數(shù)后取其排序的倒數(shù)來(lái)計(jì)算每個(gè)結(jié)果集中每個(gè)產(chǎn)品的排序。這個(gè)常數(shù)可以防止排名靠前的產(chǎn)品主導(dǎo)最終得分,并允許排名較低的產(chǎn)品做出有意義的貢獻(xiàn)。

2. 對(duì)來(lái)自所有結(jié)果集的排序倒數(shù)求和,以獲得產(chǎn)品的最終RRF分?jǐn)?shù)。

針對(duì)關(guān)鍵字搜索,Postgres提供了一個(gè)排序函數(shù)ts_rank(和一些變),它可以用作結(jié)果集中產(chǎn)品的排序。針對(duì)語(yǔ)義搜索,我們可以使用嵌入距離來(lái)計(jì)算結(jié)果集中產(chǎn)品的排序。它可以SQL來(lái)實(shí)現(xiàn),使用每種搜索方法的CTE,最后將它們組合起來(lái)。

此外,我們還可以在合并后使用機(jī)器學(xué)習(xí)模型對(duì)結(jié)果重新排序。由于計(jì)算成本高,在初始檢索后運(yùn)用基于機(jī)器學(xué)習(xí)模型的重新排序,將結(jié)果集縮減到一小部分有希望的候選對(duì)象。

結(jié)論

借助上述組件,我們構(gòu)建了一個(gè)智能搜索管道,它集成了以下部分

  • 全文搜索,面向精確的關(guān)鍵字匹配
  • 向量搜索,面向語(yǔ)義匹配
  • 結(jié)果融合,使用機(jī)器學(xué)習(xí)結(jié)合結(jié)果和重新排序

我們通過(guò)使用存儲(chǔ)所有數(shù)據(jù)的單一數(shù)據(jù)庫(kù)系統(tǒng)來(lái)做到這一點(diǎn)。由于避免與單獨(dú)的搜索引擎或數(shù)據(jù)庫(kù)集成,我們就不需要擁有多個(gè)技術(shù)堆棧,并降低了系統(tǒng)的復(fù)雜性。

原文標(biāo)題:Hybrid Search Using Postgres DB,作者:Suraj Dharmapuram

責(zé)任編輯:華軒 來(lái)源: 51CTO
相關(guān)推薦

2022-08-30 08:00:00

架構(gòu)數(shù)據(jù)庫(kù)Postgres

2021-09-13 06:33:27

遠(yuǎn)程工作ITCIO

2014-10-14 09:49:47

Postgres數(shù)據(jù)庫(kù)

2024-01-10 16:01:28

2021-12-02 07:50:31

混合云專(zhuān)線機(jī)房

2024-01-23 18:53:04

PostgreSQL關(guān)系數(shù)據(jù)庫(kù)

2021-04-01 14:20:41

混合云私有云云計(jì)算

2017-11-13 06:35:47

混合云應(yīng)用程序DevOps

2013-03-13 10:17:50

混合云混合云模式構(gòu)建混合云

2021-10-08 10:05:31

DorkifyGoogle Dork漏洞

2012-11-12 10:30:25

IBMdw

2022-06-13 07:48:34

混合軟件產(chǎn)品

2013-05-14 10:44:19

混合云Windows AzuApp Control

2013-04-07 10:00:18

2010-11-03 14:28:15

DB2行轉(zhuǎn)列

2010-11-04 13:50:20

DB2在線導(dǎo)入

2018-08-22 14:25:42

搜索LuceneQuery

2022-11-15 18:31:37

React

2010-08-10 17:10:46

2013-11-13 10:21:42

混合云服務(wù)私有數(shù)據(jù)中心公共云
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)