Python快速進(jìn)修指南之向量數(shù)據(jù)庫(kù)文本搜索
前言
如果說(shuō)Python是跟隨我的步伐學(xué)習(xí)的話,我覺(jué)得我在日常開(kāi)發(fā)方面已經(jīng)沒(méi)有太大的問(wèn)題了。然而,由于我沒(méi)有Python開(kāi)發(fā)經(jīng)驗(yàn),我思考著應(yīng)該寫(xiě)些什么內(nèi)容。我回想起學(xué)習(xí)Java時(shí)的學(xué)習(xí)路線,直接操作數(shù)據(jù)庫(kù)是其中一項(xiàng)重要內(nèi)容,無(wú)論使用哪種編程語(yǔ)言,與數(shù)據(jù)庫(kù)的交互都是不可避免的。然而,直接操作MySQL數(shù)據(jù)庫(kù)似乎缺乏趣味性,畢竟每天都在寫(xiě)SQL語(yǔ)句。突然我想到了我之前寫(xiě)過(guò)的一系列私人知識(shí)庫(kù)文章,于是我想到了向量數(shù)據(jù)庫(kù),畢竟這是當(dāng)前非常熱門(mén)的技術(shù)之一。
如果AI離開(kāi)了向量數(shù)據(jù)庫(kù),就好像失去了靈魂一樣。市面上有很多向量數(shù)據(jù)庫(kù)產(chǎn)品,我選擇了最近騰訊推出的向量數(shù)據(jù)庫(kù),并且我還有一張免費(fèi)試用卡,趁著還沒(méi)過(guò)期,我決定寫(xiě)一些相關(guān)文章。而且我看了一下,這個(gè)數(shù)據(jù)庫(kù)對(duì)于新手來(lái)說(shuō)非常友好,因?yàn)樗锌梢暬缑?。?duì)于一個(gè)新手來(lái)說(shuō),能夠看到實(shí)際效果是最客觀的。就像當(dāng)初學(xué)習(xí)SQL時(shí),如果沒(méi)有Navicat這個(gè)可視化工具,就會(huì)感覺(jué)力不從心一樣。
向量數(shù)據(jù)庫(kù)
向量數(shù)據(jù)庫(kù)具有將復(fù)雜的非結(jié)構(gòu)化數(shù)據(jù)轉(zhuǎn)化為多維邏輯坐標(biāo)值的能力,簡(jiǎn)而言之,它可以將我們所了解的所有事物轉(zhuǎn)化為可計(jì)算的數(shù)字。一旦數(shù)據(jù)進(jìn)入數(shù)學(xué)領(lǐng)域,我們就能夠?qū)ζ溥M(jìn)行計(jì)算。此外,向量數(shù)據(jù)庫(kù)還可以作為一個(gè)外部知識(shí)庫(kù),為大型模型提供最新、最全面的信息,以應(yīng)對(duì)需要及時(shí)回答的問(wèn)題。同時(shí),它也能夠賦予大型語(yǔ)言模型長(zhǎng)期記憶的能力,避免在對(duì)話過(guò)程中產(chǎn)生"斷片"的情況。可以說(shuō),向量數(shù)據(jù)庫(kù)是大型語(yǔ)言模型的最佳合作伙伴。
如果你對(duì)任何內(nèi)容有任何疑問(wèn),請(qǐng)看以下官方文檔鏈接查看更多信息:
https://d7e.jb51.net//202401/tools/1113tusoutuanli.rar
雖然這是官方的文檔,里面存在許多錯(cuò)誤,我已經(jīng)積極提供了反饋,但可惜沒(méi)有得到有效處理。盡管如此,這并不會(huì)妨礙我們的閱讀。文檔最后還有一個(gè)官方的案例代碼倉(cāng)庫(kù),對(duì)于有興趣的同學(xué)可以直接滑動(dòng)到最后進(jìn)行查閱。不過(guò),對(duì)于新手而言,可能并不太友好,原因在于代碼量較大,很難一下子消化。就好比剛學(xué)習(xí)Java的時(shí)候,要看別人的業(yè)務(wù)邏輯一樣,即使有大量注釋,也會(huì)感到吃力。
建立數(shù)據(jù)庫(kù)連接
領(lǐng)取完畢后,你需要?jiǎng)?chuàng)建一個(gè)新的免費(fèi)示例,這個(gè)過(guò)程不難,大家都會(huì)。成功之后,你需要開(kāi)啟外網(wǎng)訪問(wèn),否則無(wú)法進(jìn)行本地的測(cè)試和聯(lián)調(diào)。在開(kāi)啟外網(wǎng)訪問(wèn)時(shí),需要將外網(wǎng)白名單ip設(shè)置為0.0.0.0/0,這將接受所有IP的請(qǐng)求。

好的,接下來(lái)我們需要獲取數(shù)據(jù)庫(kù)的登錄名和密碼。這些信息將用于連接和管理數(shù)據(jù)庫(kù)。

創(chuàng)建數(shù)據(jù)庫(kù)
import tcvectordb
from tcvectordb.model.enum import FieldType, IndexType, MetricType, ReadConsistency
#create a database client object
client = tcvectordb.VectorDBClient(url='http://*******', username='root', key='1*******', read_consistency=ReadConsistency.EVENTUAL_CONSISTENCY, timeout=30)
# create a database
db = client.create_database(database_name='db-xiaoyu')
print(db.database_name)
# list databases
db_list = client.list_databases()
for db in db_list:
print(db.database_name)
好的,我們現(xiàn)在開(kāi)始替換所需的內(nèi)容,完成數(shù)據(jù)庫(kù)的創(chuàng)建。一旦數(shù)據(jù)庫(kù)創(chuàng)建完成,我們還需要?jiǎng)?chuàng)建集合,而不是傳統(tǒng)的表,因?yàn)樵谙蛄繑?shù)據(jù)庫(kù)中,它們被稱為集合。因此,我們接下來(lái)要?jiǎng)?chuàng)建集合。
創(chuàng)建集合
創(chuàng)建集合和創(chuàng)建表的過(guò)程類似,但前提是集合需要存儲(chǔ)向量,而表用于存儲(chǔ)數(shù)據(jù)。在這里,我們選擇使用集成了embedding的集合。如果不使用集成的embedding,你需要使用其他embedding模型來(lái)輸出向量,然后將其輸入到集合中進(jìn)行存儲(chǔ)。除非你想手動(dòng)輸入向量值,否則這是必要的。
設(shè)計(jì)索引(不是設(shè)計(jì) Collection 的結(jié)構(gòu))
在使用向量對(duì)應(yīng)的文本字段時(shí),不建議建立索引。這樣做會(huì)占用大量?jī)?nèi)存資源,而且沒(méi)有實(shí)際作用。除了向量對(duì)應(yīng)的文本字段外,如果需要進(jìn)行業(yè)務(wù)過(guò)濾,也就是在查詢時(shí)需要使用where條件,那么必須單獨(dú)為這個(gè)條件字段定義一個(gè)索引。也就是說(shuō),你需要用哪個(gè)字段進(jìn)行過(guò)濾,就必須為該字段定義一個(gè)索引。向量數(shù)據(jù)庫(kù)支持動(dòng)態(tài)模式(Schema),在寫(xiě)入數(shù)據(jù)時(shí)可以寫(xiě)入任意字段,無(wú)需提前定義,類似于MongoDB。目前,主鍵id和向量字段vector是固定且必需的,字段名稱也必須一致,否則會(huì)報(bào)錯(cuò)。
在之前講解私人知識(shí)庫(kù)的時(shí)候,我會(huì)單獨(dú)引入其他embedding模型,因?yàn)橄蛄繑?shù)據(jù)庫(kù)沒(méi)有繼承這些模型。不過(guò),騰訊已經(jīng)將embedding模型集成在了他們的系統(tǒng)中,這樣就不需要來(lái)回尋找模型了。需要注意的是,為了確保一致性,你選擇的embedding模型后面的vector字段要設(shè)置為768維。
db = client.database('db-xiaoyu')
# -- index config
index = Index(
FilterIndex(name='id', field_type=FieldType.String, index_type=IndexType.PRIMARY_KEY),
VectorIndex(name='vector', dimension=768, index_type=IndexType.HNSW,
metric_type=MetricType.COSINE, params=HNSWParams(m=16, efconstruction=200)),
FilterIndex(name='author', field_type=FieldType.String, index_type=IndexType.FILTER),
FilterIndex(name='bookName', field_type=FieldType.String, index_type=IndexType.FILTER)
)
# Embedding config
ebd = Embedding(vector_field='vector', field='text', model=EmbeddingModel.BGE_BASE_ZH)
# create a collection
coll = db.create_collection(
name='book-xiaoyu',
shard=1,
replicas=0,
description='this is a collection of test embedding',
embedding=ebd,
index=index
)
print(vars(coll))
我們已經(jīng)成功創(chuàng)建了數(shù)據(jù)庫(kù)和集合,并且現(xiàn)在讓我們來(lái)看一下它們的結(jié)構(gòu)。實(shí)際上,它們的原理與MySQL和其他數(shù)據(jù)庫(kù)相似,只是存儲(chǔ)的內(nèi)容和術(shù)語(yǔ)發(fā)生了變化。我們可以將其視為數(shù)據(jù)庫(kù)操作。

插入/替換數(shù)據(jù)
當(dāng)插入數(shù)據(jù)時(shí),如果集合中已經(jīng)存在具有相同ID的文檔,則會(huì)刪除原始文檔并插入新的文檔數(shù)據(jù)。需要注意的是,很多字段我們都沒(méi)有指定,例如page、text等。你可以繼續(xù)添加這些字段,因?yàn)樗鼈冾愃朴贛ongoDB。但請(qǐng)注意,text字段必須與你在配置embedding時(shí)指定的字段相同,否則無(wú)法將其轉(zhuǎn)換為向量。
coll = db.collection('book-emb')
# 寫(xiě)入數(shù)據(jù)。
# 參數(shù) build_index 為 True,指寫(xiě)入數(shù)據(jù)同時(shí)重新創(chuàng)建索引。
res = coll.upsert(
documents=[
Document(id='0001', text="話說(shuō)天下大勢(shì),分久必合,合久必分。", author='羅貫中', bookName='三國(guó)演義', page=21),
Document(id='0002', text="混沌未分天地亂,茫茫渺渺無(wú)人間。", author='吳承恩', bookName='西游記', page=22),
Document(id='0003', text="甄士隱夢(mèng)幻識(shí)通靈,賈雨村風(fēng)塵懷閨秀。", author='曹雪芹', bookName='紅樓夢(mèng)', page=23)
],
build_index=True
)
當(dāng)我們完成數(shù)據(jù)插入后,我們可以立即執(zhí)行查詢操作。但請(qǐng)注意,如果你將 “build_index” 字段設(shè)置為 “false”,即使插入成功,查詢時(shí)也無(wú)法檢索到數(shù)據(jù)。因此,如果要立即生效并能查詢到數(shù)據(jù),你必須將其設(shè)置為 “true”。這個(gè)是重建索引的過(guò)程
查詢數(shù)據(jù)
這里的查詢可以分為精確查詢和相似度查詢兩種。精確查詢是指除了向量字段外的其他字段查詢條件都是精確匹配的。由于我們?cè)诮⑺饕龝r(shí)已經(jīng)對(duì)作者(author)和書(shū)名(bookName)建立了索引,所以我們可以直接對(duì)它們進(jìn)行數(shù)據(jù)過(guò)濾,但是我不會(huì)在這里演示?,F(xiàn)在我將演示一下模糊查詢,即對(duì)向量字段匹配后的結(jié)果進(jìn)行查詢,并同時(shí)加上過(guò)濾條件。
doc_lists = coll.searchByText(
embeddingItems=['天下大勢(shì),分久必合,合久必分'],
filter=Filter(Filter.In("bookName", ["三國(guó)演義", "西游記"])),
params=SearchParams(ef=200),
limit=3,
retrieve_vector=False, # 不返回向量
output_fields=['bookName','author']
)
# printf
for i, docs in enumerate(doc_lists.get("documents")):
for doc in docs:
print(doc)
除了上面提到的Python的寫(xiě)法,我們還可以通過(guò)界面來(lái)進(jìn)行精確查詢。只需要在界面中填寫(xiě)where后的條件即可。

要進(jìn)行模糊查詢,可以直接使用text文字進(jìn)行查詢,或者定義過(guò)濾字段來(lái)進(jìn)行查詢優(yōu)化。

總結(jié)
剩下的刪除數(shù)據(jù)這部分我就不演示了。今天先跟向量數(shù)據(jù)庫(kù)熟悉一下界面操作,感覺(jué)就像在使用Kibana查詢ES數(shù)據(jù)一樣。不知道你們有沒(méi)有類似的感覺(jué)。好了,今天我們先只關(guān)注文本操作,下一期我會(huì)嘗試處理圖像或者視頻數(shù)據(jù)??偟膩?lái)說(shuō),相比Java,Python的SDK使用起來(lái)更加舒適。如果你曾經(jīng)使用過(guò)Java SDK與平臺(tái)接口對(duì)接,就會(huì)發(fā)現(xiàn)Python SDK上手更快。
以上就是Java開(kāi)發(fā)快速進(jìn)修Python指南之向量數(shù)據(jù)庫(kù)文本搜索的詳細(xì)內(nèi)容,更多關(guān)于Python向量數(shù)據(jù)庫(kù)文本搜索的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Python實(shí)現(xiàn)搜索Google Scholar論文信息的示例代碼
- 編寫(xiě)Python腳本來(lái)獲取Google搜索結(jié)果的示例
- Python flashtext文本搜索和替換操作庫(kù)功能使用探索
- python打開(kāi)瀏覽器并模擬搜索示例詳解
- AI與Python人工智能啟發(fā)式搜索概念理解
- python高級(jí)搜索實(shí)現(xiàn)高效搜索GitHub資源
- python實(shí)現(xiàn)精準(zhǔn)搜索并提取網(wǎng)頁(yè)核心內(nèi)容
- python GoogleIt庫(kù)實(shí)現(xiàn)在Google搜索引擎上快速搜索
相關(guān)文章
python如何實(shí)現(xiàn)wifi自動(dòng)連接,解決電腦wifi經(jīng)常斷開(kāi)問(wèn)題
這篇文章主要介紹了python實(shí)現(xiàn)wifi自動(dòng)連接,解決電腦wifi經(jīng)常斷開(kāi)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
Python 數(shù)據(jù)結(jié)構(gòu)之堆棧實(shí)例代碼
這篇文章主要介紹了Python 數(shù)據(jù)結(jié)構(gòu)之堆棧實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-01-01
Python flask框架實(shí)現(xiàn)瀏覽器點(diǎn)擊自定義跳轉(zhuǎn)頁(yè)面
這篇文章主要介紹了Python flask框架實(shí)現(xiàn)瀏覽器點(diǎn)擊自定義跳轉(zhuǎn)頁(yè)面,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
PyTorch搭建雙向LSTM實(shí)現(xiàn)時(shí)間序列負(fù)荷預(yù)測(cè)
這篇文章主要為大家介紹了PyTorch搭建雙向LSTM實(shí)現(xiàn)時(shí)間序列負(fù)荷預(yù)測(cè),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Python使用Flask Migrate模塊遷移數(shù)據(jù)庫(kù)
Flask-Migrate是一個(gè)為Flask應(yīng)用處理SQLAlchemy數(shù)據(jù)庫(kù)遷移的擴(kuò)展,使得可以通過(guò)Flask的命令行接口或者Flask-Scripts對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作2022-07-07
Python3和PyCharm安裝與環(huán)境配置【圖文教程】
這篇文章主要介紹了Python3和PyCharm安裝與環(huán)境配置,結(jié)合圖文形式詳細(xì)分析了Python3和PyCharm的安裝、環(huán)境配置、測(cè)試命令及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2020-02-02

