【2025最新】使用neo4j實現GraphRAG所需的向量檢索

學習筆記,比較混亂,介意慎點。

背景

在將UMLS或者LightRAG構造的數據庫存入neo4j之后,我開始將知識圖譜運用到實際場景的使用中、例如查詢、推理。然而,由于字符串匹配導致大量術語在檢索時出現缺失。導致檢索效果不佳。我們需要使用embedding模型,將對應的實體或者關系轉為vector,存入向量數據庫。利用向量數據庫已有的高效存儲技術和查詢方法。幫助我們快速查詢到相關實體或者關系。通過確定相似度的閾值,來保留最終查詢結果。

目標:

? ? ? ? 向量化UMLS的實體(篩選過的)

? ? ? ? embeding 千問的嵌入模型? ? ? ??

? ? ? ? 向量數據庫?在實踐中,我們推薦大家使用開源 Milvus,或它的全托管版本 Zilliz Cloud,來存儲并搜索 graph 結構中大量的 entities 和 relationships。(AI大模型:知識圖譜融入向量數據庫,帶來 RAG 效果飛升(附教程)_知識圖譜 向量數據庫-CSDN博客)

在這句話中,“全托管” 指的是一種軟件服務模式,具體來說,Zilliz Cloud 作為 Milvus 向量數據庫的全托管版本,意味著用戶無需自行搭建、部署、維護數據庫的底層基礎設施(如服務器、存儲、網絡等),也無需手動處理數據庫的安裝、配置、更新、備份、擴容等運維工作,這些任務全部由服務提供商(此處即 Zilliz 團隊)來負責。

用戶只需通過簡單的接口或控制臺操作,就能直接使用數據庫的核心功能(如存儲、搜索向量數據等),專注于自身業務邏輯的開發,而不必投入精力在基礎設施管理上。這種模式的優勢在于降低了技術門檻、減少了運維成本,同時能借助專業團隊的維護保障服務的穩定性和安全性,常見于云服務中的數據庫、服務器等領域。

全托管版本 Zilliz Cloud收費嗎?

Zilliz Cloud 有免費版本,也有付費版本,具體如下:

  • 免費版本:Serverless cluster 是 Zilliz Cloud 的入門版本,用戶可在 GCP 上部署免費 cluster,適合入門者和想要嘗試 Zilliz Cloud 的開發人員,無需信用卡和復雜配置,即可快速體驗向量數據庫功能。
  • 付費版本:包括標準版、企業版和專有部署版。標準版適合小型團隊和個人開發者,支持在 AWS 和 GCP 上部署,注冊可獲贈價值 $100 的 credit,享受 30 天免費試用。企業版適合大型組織或企業,提供高可用、數據安全和專家技術支持等。專有部署版適用于高度注重數據隱私和合規的場景,這兩種版本無免費試用,具體價格需根據用戶實際使用情況和配置確定。

學習過程

? ? ? ? 通過博文了解使用的具體過程為:定義數據模式,(包括知道dim = 1536 # OpenAI embedding維度),創建存放向量的集合,寫入

代碼比較簡單,如下:

# 定義數據模式
collection_name = "products"
dim = 1536  # OpenAI embedding維度
# 創建集合
collection = Collection(name=collection_name)
collection.create_field(FieldSchema("id", DataType.INT64, is_primary=True))
collection.create_field(FieldSchema("title", DataType.VARCHAR, max_length=200))
collection.create_field(FieldSchema("description", DataType.VARCHAR, max_length=2000))
collection.create_field(FieldSchema("embedding", DataType.FLOAT_VECTOR, dim=dim))
# 寫入數據
with collection:for index, row in df.iterrows():embedding = get_embedding(row.title + " " + row.description)collection.insert([[index], [row.title], [row.description], [embedding]])

向量數據庫可能會返回那些字符表面相似,但是語義不相似的內容,這會造成“上下文污染”,使得大語言模型生成的推薦不夠精確。

這里的解決是把一個概念的所有特征用知識圖譜檢索出來,把特征和原有的描述一起向量化檢索。

再用知識圖譜對向量化檢索結果進一步處理,例如:# 篩選出真正具備防水和跑步功能的產品
query = """ SELECT ?product ?title ?description WHERE { ?product hasFeature ?feature1. ?product hasFeature ?feature2. ?product name ?title. ?product description ?description. FILTER (?product IN (%s) && ?feature1 IN (%s) && ?feature2 IN (%s)) } """

(等我回來好好品一下這個查詢

我懂了,核心就是各種同時滿足已知條件。如select product,如何滿足一堆feature

? )

上面我們已經大概有個印象了。接下來開始對比開源 Milvus,或它的全托管版本 Zilliz Cloud,我們選哪個,由于我非常趕時間,需要決策一個技術選型并且快速收集情報進行了解,再部署。

學習[深入了解Zilliz Cloud與Milvus:從安裝到應用的全方位指南]_milvus安裝-CSDN博客

高效向量搜索與管理:使用Zilliz Cloud和Milvus_milvus zilliz-CSDN博客

一文帶你入門向量數據庫milvus:含docker安裝、milvus安裝使用、attu 可視化,完整指南啟動 Milvus 進行了向量相似度搜索-CSDN博客

Milvus 向量數據庫介紹及使用-CSDN博客

決定了,其實對我來說都差不多,我決定安裝Milvus,作為一個開源的軟件,學習它對我來說未來的可用性更強。邊學邊做吧。

?概念學習

最火向量數據庫Milvus安裝使用一條龍!_milvus安裝腳本-CSDN博客從該博客學了不少的概念和了解,我的理念是要學就要盡量了解自己在用的是什么,為甚要用它。

向量數據庫是大模型應用開發必備組件之一,因為它在知識庫、語義搜索、檢索增強生成(RAG)等人工智能應用中發揮著舉足輕重的作用。但向量數據有很多,為什么要使用 Milvus 呢?
常見的向量數據庫有以下這些:

Chroma
Elasticsearch
Milvus
Neo4j
OpenSearch
Redis
PGVector
然而目前市面上使用最多的向量數據庫還是 Milvus,為什么呢?


Milvus 設計之初就是為 AI 而生的一個高效的向量數據庫系統,在大多數情況下,Milvus 的性能是其他向量數據庫的 2-5 倍,它能實現萬億級向量毫秒級相似性搜索,而且 Milvus 還是開源的向量數據庫。

PS:也就說 Milvus 既開源(可以免費使用+支持二次開發)又具備高性能,這樣的數據庫誰不愛呢?

為什么 Milvus 這么快?
Milvus 運行比較快的原因有以下幾個:

硬件感知優化:為了讓 Milvus 適應各種硬件環境,我們專門針對多種硬件架構平臺優化了其性能,包括 AVX512、SIMD、GPU 和 NVMe SSD。
高級搜索算法:Milvus 支持多種內存和磁盤索引/搜索算法,包括 IVF、HNSW、DiskANN 等,所有這些算法都經過了深度優化。與 FAISS 和 HNSWLib 等流行實現相比,Milvus 的性能提高了 30%-70%。
C++ 搜索引擎:向量數據庫性能的 80% 以上取決于其搜索引擎。由于 C++ 語言的高性能、底層優化和高效資源管理,Milvus 將 C++ 用于這一關鍵組件。最重要的是,Milvus 集成了大量硬件感知代碼優化,從匯編級向量到多線程并行化和調度,以充分利用硬件能力
面向列:Milvus 是面向列的向量數據庫系統。其主要優勢來自數據訪問模式。在執行查詢時,面向列的數據庫只讀取查詢中涉及的特定字段而不是整行,這大大減少了訪問的數據量。此外,對基于列的數據的操作可以很容易地進行向量化,從而可以一次性在整個列中應用操作,進一步提高性能。


Milvus 支持的搜索類型
Milvus 支持各種類型的搜索功能,以滿足不同用例的需求:

ANN 搜索:查找最接近查詢向量的前 K 個向量。
過濾搜索:在指定的過濾條件下執行 ANN 搜索
范圍搜索:查找查詢向量指定半徑范圍內的向量。
混合搜索:基于多個向量場進行 ANN 搜索。
全文搜索:基于 BM25 的全文搜索。
Rerankers:根據附加標準或輔助算法調整搜索結果順序,完善初始 ANN 搜索結果。
根據主鍵檢索數據。
查詢使用特定表達式檢索數據。


Milvus 安裝
Milvus 有三種部署方式:

Milvus Lite:Milvus Lite 是一個 Python 庫,可導入到您的應用程序中。作為 Milvus 的輕量級版本,它非常適合在 Jupyter 筆記本或資源有限的智能設備上運行快速原型。Milvus Lite 支持與 Milvus 其他部署相同的 API。與 Milvus Lite 交互的客戶端代碼也能與其他部署模式下的 Milvus 實例協同工作。
Milvus Standalone:Milvus Standalone 是單機服務器部署。Milvus Standalone 的所有組件都打包到一個 Docker 鏡像中,部署起來非常方便。
Milvus Distributed:Milvus Distributed 可部署在 Kubernetes 集群上。這種部署采用云原生架構,攝取負載和搜索查詢分別由獨立節點處理,允許關鍵組件冗余。它具有最高的可擴展性和可用性,并能靈活定制每個組件中分配的資源。Milvus Distributed 是在生產中運行大規模向量搜索系統的企業用戶的首選。
PS:當然中小型公司生產環境也可以直接購買 XXX 云的 Milvus 實例直接使用。

我們這里使用 Milvus Standalone 單機版部署方式。

硬件要求

如何確定自己的電腦性能:

有幾核:按 Win + R 輸入 “cmd” 后按回車,打開命令提示符。輸入命令 “wmic CPU get NumberOfCores,NumberOfLogicalProcessors” 并回車,輸出會顯示核心數(NumberOfCores)和邏輯處理器數。

CPU型號:任務管理器:右鍵點擊任務欄,選擇 “任務管理器”,或使用快捷鍵 Ctrl + Shift + Esc 直接打開。在任務管理器中,點擊 “性能” 標簽,選擇 “CPU”

安裝

0.如何確定自己有沒有安裝docker desktop、wsl

????????Docker Desktop:在 Windows、macOS 或 Linux 系統中,打開命令提示符、PowerShell 或終端,輸入 “docker --version” 或 “docker version” 命令。若顯示 Docker 的版本信息,則說明已安裝。還可輸入 “docker info” 命令,若能獲取到 Docker 系統的詳細信息,如鏡像數量、容器數量等,也表明已安裝且服務正常運行。

【pps,我突然想到,自己安裝只能安裝在windows,而未來公司用多半是服務器或者linux系統。我裝在學校服務器的話,容易遇到服務器維護,沒卡啥的,還是調接口吧,或者直接調用之前的neo4j。于是以下廢棄,歡迎大家調到下一個一級標題】

1.安裝wsl

2從安裝到測試安裝完成【Windows系統】向量數據庫Milvus安裝教程-CSDN博客

一些我的小疑問

????????Docker 是一種開源的容器化技術,通過 “容器” 封裝應用程序及其所有依賴的底層系統環境(如操作系統庫、配置文件、系統工具等),實現 “一次構建,到處運行”。
容器與宿主機系統隔離,確保應用在不同操作系統(如 Windows、Linux、macOS)或服務器上的運行環境完全一致,解決 “在我這能跑,在你那跑不了” 的問題。

???????? 容器類似輕量級虛擬機,包含應用運行所需的代碼、庫、環境變量等,但共享主機操作系統內核,啟動快、資源占用低。 通過 Docker,開發者可在一致環境中開發、測試和部署應用,也便于規模化管理和分發應用。

? ? ? ? ?Docker Compose 是 Docker 官方提供的用于定義和運行多容器 Docker 應用程序的工具,通過 YAML 文件配置應用所需的所有服務,再用一條命令即可創建并啟動所有服務。

? ? ? ? ? 在該場景中,安裝 Milvus 服務需使用其提供的 docker - compose.yml 文件,而 Docker Compose 正是解析和執行該文件的必備工具,只有安裝它,才能通過 “docker - compose up -d” 命令啟動 Milvus 相關的容器服務。

? ? ? ??

Docker Desktop 是一款適用于 Windows 和 macOS 系統的桌面應用程序,是 Docker 官方提供的集成工具

它的主要功能包括:

  • 提供圖形化界面,方便用戶管理 Docker 容器、鏡像、網絡等資源,無需完全依賴命令行操作。
  • 內置了 Docker Engine,可在本地構建、運行和測試 Docker 容器。
  • 集成了 Docker Compose 工具,支持通過配置文件定義和運行多容器應用。
  • 對于 Windows 系統,通常需要配合 WSL(Windows 子系統 for Linux)使用,以提供更高效的容器運行環境。

簡單來說,它是簡化本地 Docker 環境搭建和使用的工具,讓開發者能更便捷地進行容器化應用的開發、測試等工作。

neo4j

Neo4j 的向量搜索(Neo4jVector)和常見的向量數據庫(比如 Milvus、Qdrant)之間的區別與聯系_neo4j向量化-CSDN博客

根據上文,感覺neo4j更適合我的研究,開源現由特定節點出發,再沿著圖結構查詢

Neo4j 向量搜索擅長將“結構化圖信息”與“語義相似度”結合起來;而 Milvus、Qdrant 等專用向量數據庫更適合做超大規模、高性能的純向量相似度檢索。

存入向量數據庫

【neo4j】win/linux安裝和使用+cypher+langchian+向量索引_neo4j desktop linux-CSDN博客

通過上文對條件再做個了解

向量索引內容
neo4j版本5以上,部分函數要求5.18以上
官網介紹Vector indexes - Cypher Manual
csdn給出的安裝方法Neo4j安裝apoc插件的詳細教程-CSDN博客

根據上文完成了安裝apoc

原因如下:

neo4j有兩種索引方式,一種是索引文本(整個三元組full-text,即Relationship),一種是向量化Node或者Relation。
full-text向量化Full-text indexes - Cypher Manual
貌似不能向量化整個三元組?

官網向量化例子
同理,添加關系的embedding函數是db.create.setRelationshipVectorProperty
官網代碼1Cypher Cheat Sheet - Neo4j Documentation Cheat Sheet
官網代碼2Find movies given a search prompt - Embeddings & Vector Indexes Tutorial

def add_vectors():model = BertEmb()  # 自定義的 model.embed_query(str) 返回一個list 裝的是embedding# step1: get embeddingscode = "MATCH (e) RETURN e.id as id, e.name as name"entity_names = driver.execute_query(code)entity_list = []print(f'Begin generate embeddings ...')for idx, record in enumerate(tqdm(entity_names.records)):id = record.get('id')name = record.get('name')curr_emb = {'id': id,'name': name,'embedding': model.embed_query(name)}   entity_list.append(curr_emb)# step2: set NodeVectorPropertyprint(f'Begin adding embeddings as property...')batch = 100total_num = len(entity_names.records)pbar = tqdm(total=total_num)for step in range(0, total_num, batch):range_start = steprange_end = min(total_num, range_start+batch)batch_entities = entity_list[range_start:range_end]create_embeddings_code = """UNWIND $entities as entityMATCH (e:Entity {id:entity.id})CALL db.create.setNodeVectorProperty(e, 'embedding', entity.embedding)"""driver.execute_query(create_embeddings_code, entities=batch_entities)        pbar.update(range_end-range_start) pbar.close()# step3: add indexprint(f'Begin adding index...')create_index_code = """CREATE VECTOR INDEX entity_embeddings IF NOT EXISTSFOR (e:Entity)ON e.embeddingOPTIONS {indexConfig: {`vector.dimensions`: 768,`vector.similarity_function`: 'cosine'}}"""driver.execute_query(create_index_code)

具體操作

在 Neo4j 中實現向量化存儲:從文本到高效語義搜索_neo4j 向量化-CSDN博客

neo4j圖數據庫基本概念和向量使用_neo4j_辛一一-DeepSeek技術社區

1.數據填充
假設你有一些文本數據(例如一個文本文件 dune.txt),需要將這些文本數據處理后存儲到 Neo4j 中。這通常需要以下步驟:

讀取文本數據:從文件中讀取文本內容。
分段處理:將文本分割成較小的段落或句子。
生成向量:使用某種嵌入模型(如 OpenAI 的 text-embedding-ada-002 或 Hugging Face 的 sentence-transformers)將文本轉換為向量。
存儲到 Neo4j:將文本和對應的向量存儲到 Neo4j 數據庫中。
以下是一個簡單的 Python 示例代碼,展示如何完成這些步驟:

import os
import neo4j
from transformers import AutoModel, AutoTokenizer
import torch# 1.連接到 Neo4j 數據庫
uri = os.getenv("NEO4J_URI")
username = os.getenv("NEO4J_USERNAME")
password = os.getenv("NEO4J_PASSWORD")
driver = neo4j.GraphDatabase.driver(uri, auth=(username, password))# 2.加載文本嵌入模型
model_name = "sentence-transformers/all-MiniLM-L6-v2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name)# 3.讀取文本文件
with open("dune.txt", "r") as file:text = file.read()# 4.分段處理文本
paragraphs = text.split("\n\n")  # 假設每兩行是一個段落# 5.將文本和向量存儲到 Neo4j
def store_paragraphs(paragraphs):with driver.session() as session:for i, paragraph in enumerate(paragraphs):# 生成向量inputs = tokenizer(paragraph, return_tensors="pt", padding=True, truncation=True)outputs = model(**inputs)vector = outputs.last_hidden_state.mean(dim=1).detach().numpy().tolist()[0]# 存儲到 Neo4jsession.run("""CREATE (p:Paragraph {id: $id, text: $text, embedding: $embedding})""",id=i,text=paragraph,embedding=vector)store_paragraphs(paragraphs)

下面是我根據上面代碼進行的一些定制化修改

1. 鏈接的信息從一開始安裝neo4j時候的來,等號右邊換成字符串就行。

2.嵌入用的是Qwen/Qwen3-Embedding-8B,從硅基流動用戶系統,統一登錄 SSO調用,需要付費,但不用部署。教程如下:創建嵌入請求 - SiliconFlow

import requestsurl = "https://api.siliconflow.cn/v1/embeddings"payload = {"model": "BAAI/bge-large-zh-v1.5","input": "Silicon flow embedding online: fast, affordable, and high-quality embedding services. come try it out!"
}
headers = {"Authorization": "Bearer <token>","Content-Type": "application/json"
}response = requests.request("POST", url, json=payload, headers=headers)print(response.text)

3.我要文本化的內容是neo4j中已有Concept節點的name屬性,type屬性的值,并將向量后的內容加入知識圖譜Concept節點中的兩個向量屬性,concept節點示例如下:

{"identity": 8,"labels": ["Concept"],"properties": {"CUI": "C0187921","name": "Radical resection for tumor of fibula","type": ["Therapeutic or Preventive Procedure"  ]},"elementId": "4:6cab5d42-4d85-48d7-be0d-9c5b8f464282:8"
}

4.我要在neo4jConcept節點中新添的兩個屬性中增加向量索引

5.完成需要的查詢語句

? ? ? ? 給出一個名詞,查出0.8閾值以上的top3節點

6.關系的RELA也變成向量,如果關系能被抽取的化,后續開源單獨匹配(但是太麻煩了不想考慮,之后再說吧)

2:創建向量索引

????????

在 Neo4j 中,為了高效地查詢向量數據,需要創建向量索引。向量索引可以幫助快速計算向量之間的相似性。

以下是一個創建向量索引的 Cypher 查詢示例:

CREATE VECTOR INDEX `paragraph-embeddings`
FOR (p:Paragraph) ON (p.embedding)
OPTIONS {indexConfig: {`vector.dimensions`: 384,  // 假設向量維度是 384`vector.similarity_function`: 'cosine'  // 使用余弦相似性
}}
  • vector.dimensions:向量的維度,取決于你使用的嵌入模型。
  • vector.similarity_function:用于計算相似性的函數,常見的有余弦相似性(cosine)和歐幾里得距離(euclidean)。

3.查詢向量索引

創建索引后,可以通過向量查詢來找到與給定向量最相似的節點。以下是一個查詢示例:

CALL db.index.vector.queryNodes('paragraph-embeddings', 10, $queryVector)
YIELD node AS paragraph, score
RETURN paragraph.text AS text, score
ORDER BY score DESC
  • paragraph-embeddings:向量索引的名稱。
  • 10:返回最相似的 10 個結果。
  • $queryVector:查詢向量,你需要提前生成這個向量。

例如,如果你想查詢與某個文本最相似的段落,可以先將文本轉換為向量,然后作為?$queryVector?傳入查詢。

存進去了這么查找

使用Neo4j Vector Index進行向量相似性搜索的實戰指南_neo4jvector 使用-CSDN博客

4.

另外一種方法,在節點中設置向量屬性

如果需要為節點或關系設置向量屬性,可以使用以下 Cypher 查詢:

MATCH (n:Paragraph {id: $id})
CALL db.create.setNodeVectorProperty(n, 'embedding', $vector)
RETURN n

  • n:Paragraph:目標節點。
  • embedding:向量屬性的名稱。
  • $vector:要設置的向量值。

節點向量存儲和檢索

1.節點需要添加向量數組

可以選擇一開添加節點的時候加一個向量屬性

create (n:GroupProductA {name:'保高空',description: "保險產品可以保高空作業",embedding: [向量的具體值]}) return n

或者后續添加

MATCH (a:GroupProductA {name:'保高空' })
SET a+= { embedding: [向量具體數值] }
RETURN b;

2.給節點增加向量索引

CREATE VECTOR INDEX 索引名稱 IF NOT EXISTS
FOR (具體的節點標簽)
ON n.embedding
OPTIONS { indexConfig: {
?`vector.dimensions`: 向量維度數值,
?`vector.similarity_function`: 向量計算方法
}}

例如:

CREATE VECTOR INDEX HighDutyIdx IF NOT EXISTS
FOR (n:HighDuty)
ON n.embedding
OPTIONS { indexConfig: {
?`vector.dimensions`: 1536,
?`vector.similarity_function`: 'cosine'
}}

3.計算向量余弦相似度

MATCH (a:GroupProductA)
WHERE a.embedding IS NOT NULL
WITH n,
???? // 計算向量余弦相似度或歐氏距離
???? vector.similarity.cosine(n.embedding, [0.1, 0.2, ...]) AS similarity
RETURN n.name, similarity
ORDER BY similarity DESC
LIMIT 10;

4.查詢兩個節點的向量相似度


MATCH (a:GroupProductA {name: '保高空'})
MATCH (b:GroupProductA {name:'團意'})
RETURN vector.similarity.cosine(a.embedding, b.embedding)

5.查詢所有向量索引


SHOW VECTOR INDEXES

6.刪除指定向量索引


DROP INDEX moviePlots

三.全文索引檢索

1.要檢索前首先要創建全文索引.

CREATE FULLTEXT INDEX 索引名稱 FOR (n:標簽) ON EACH [n.節點屬性]
OPTIONS {
? indexConfig: {
??? `fulltext.analyzer`: 'cjk',
??? `fulltext.eventually_consistent`: true
? }
}

fulltext.analyzer是選用的分詞器

fulltext.eventually_consistent設置為true,索引將處于最終一致性更新模式。這意味著更新將“盡快”在后臺線程中應用,而不是像其他索引那樣在事務提交期間應用

2.查看neo4j支持哪些分詞器

call?db.index.fulltext.listAvailableAnalyzers()

3.查詢所有全文索引

SHOW FULLTEXT INDEXES

4.全文索引查詢語句

CALL db.index.fulltext.queryNodes(索引名稱, 查詢的文本) YIELD node, score
RETURN node.節點屬性, score

三.RAG向量檢索最佳實踐

1.先查詢出所有符合的向量節點,有個閾值,比如大于0.8的查詢出所有符合的節點

2.然后再通過這些符合的節點,根據節點之間的關系,找到想要查詢出來的節點屬性

3.根據查詢出來的節點屬性和用戶問題,給大模型總結

4.可以考慮用全文索引和向量索引做混合搜索的RAG

其它

LangChain 是一個用于構建基于大語言模型(LLM)的應用程序的框架。它的核心作用是將語言模型與其他工具、數據來源等進行連接和協調,讓開發者能更便捷地搭建復雜的 LLM 應用,比如問答系統、聊天機器人、智能檢索等。

從網頁內容關聯來看,LangChain 可以與 Neo4j 結合使用,實現基于知識圖譜的增強型應用。例如,借助 LangChain 調用 Neo4j 時,需要安裝 APOC 插件,并在配置文件中進行相應設置(如添加?dbms.security.procedures.unrestricted=apoc.*,algo.*),從而利用知識圖譜中的結構化數據提升 LLM 應用的準確性和邏輯性。

在這段關于Neo4j數據庫的描述中,**全文索引檢索**是一種針對節點屬性的文本內容進行高效搜索的技術,核心是通過預先創建“全文索引”,實現對節點屬性中關鍵詞、短語的快速匹配和檢索。以下是具體解析: ### 1. 核心作用 全文索引檢索的目的是解決“對節點屬性的文本內容進行靈活搜索”的需求。例如,若節點(如“電影”標簽的節點)有“簡介”屬性(包含長文本描述),通過全文索引可以快速找到包含“科幻”“導演XXX”等關鍵詞的所有節點,而無需逐行掃描所有節點的屬性,大幅提升檢索效率。 ### 2. 關鍵特點 - **依賴預創建的全文索引**:必須先通過`CREATE FULLTEXT INDEX`語句創建索引,明確要索引的節點標簽(`n:標簽`)和具體屬性(`n.節點屬性`),否則無法進行全文檢索。 - **支持分詞器配置**:通過`fulltext.analyzer`指定分詞規則(如示例中的`cjk`,適用于中文、日文、韓文等東亞語言的分詞),將文本拆分為有意義的“詞”,確保搜索時能準確匹配關鍵詞(例如中文“人工智能”會被正確拆分為“人工”“智能”,而非單個字符)。 - **索引更新模式**:`fulltext.eventually_consistent: true`表示索引采用“最終一致性”更新,即節點屬性變化后,索引不會立即更新,而是在后臺異步處理,適合對實時性要求不高但追求寫入性能的場景;若設為`false`,則索引在事務提交時同步更新,實時性高但可能影響寫入速度。 ### 3. 操作流程 - **創建索引**:通過`CREATE FULLTEXT INDEX`語句定義索引規則(關聯的節點標簽、屬性、分詞器等)。 - **查詢索引**:使用`CALL db.index.fulltext.queryNodes(索引名稱, 查詢文本)`執行檢索,返回匹配的節點(`node`)和匹配得分(`score`,得分越高表示匹配度越高)。 - **輔助操作**:可通過`call db.index.fulltext.listAvailableAnalyzers()`查看支持的分詞器,通過`SHOW FULLTEXT INDEXES`查看已創建的全文索引。 ### 4. 與RAG向量檢索的關系 文中提到“全文索引和向量索引做混合搜索的RAG”,說明兩者是互補的檢索方式: - 全文索引依賴關鍵詞匹配,適合精確查找包含特定詞匯的內容; - 向量檢索(如RAG中常用的)則通過文本語義向量的相似度匹配,適合理解“語義相關性”(例如“如何入門機器學習”和“機器學習新手教程”雖關鍵詞不同,但語義相近)。 混合使用可結合兩者優勢,提升檢索的準確性和全面性。 總結來說,全文索引檢索是Neo4j中針對文本內容的高效關鍵詞檢索方案,通過預定義索引和分詞規則,實現對節點屬性的快速文本匹配,是處理結構化圖形數據庫中文本搜索需求的重要工具。

最終我的代碼如下:

# 導入所需模塊
import os                            # 用于讀取環境變量(如Neo4j連接參數和API token)
import requests                      # 用于調用嵌入向量API
import json                          # 用于處理JSON數據
from neo4j import GraphDatabase      # 用于連接Neo4j圖數據庫
from tqdm import tqdm                # 用于添加處理進度條
import numpy as np                   # 用于處理數值型數據(雖然此處未直接使用)# ---------- 配置Neo4j連接 ----------
uri = os.getenv("NEO4J_URI", "bolt://localhost:7687")             # 支持默認本地連接
username = os.getenv("NEO4J_USERNAME", "neo4j")                   # 默認用戶名
password = os.getenv("NEO4J_PASSWORD", "xxxx")                # 默認密碼
driver = GraphDatabase.driver(uri, auth=(username, password))      # 創建Neo4j驅動器# ---------- 配置Qwen嵌入接口 ----------
API_URL = "https://api.siliconflow.cn/v1/embeddings"        # 嵌入API URL
API_MODEL = "Qwen/Qwen3-Embedding-8B"                        # 嵌入模型名
API_TOKEN = "sk-jy
xxxxx"  # 嵌入服務Token(默認示例)
HEADERS = {"Authorization": f"Bearer {API_TOKEN}",                # Bearer鑒權頭"Content-Type": "application/json"                     # 數據格式為JSON
}# ---------- 獲取向量函數 ----------
def get_embedding(text):payload = {"model": API_MODEL,"input": text}response = requests.post(API_URL, headers=HEADERS, json=payload)  # 發送POST請求if response.status_code == 200:return response.json()["data"][0]["embedding"]              # 返回嵌入向量else:print("Embedding API error:", response.text)                 # 打印錯誤信息return None# ---------- 正式批量更新Concept節點向量 ----------
def update_concepts_with_embeddings():with driver.session() as session:result = session.run("MATCH (c:Concept) RETURN elementId(c) AS eid, c.name AS name, c.type AS type")for record in tqdm(result):node_eid = record["eid"]name = record["name"]type_list = record["type"]type_str = ", ".join(type_list) if isinstance(type_list, list) else str(type_list)name_vec = get_embedding(name)type_vec = get_embedding(type_str)if name_vec:session.run("MATCH (c:Concept) WHERE elementId(c) = $eid CALL db.create.setNodeVectorProperty(c, 'name_vector', $vec) RETURN c", eid=node_eid, vec=name_vec)if type_vec:session.run("MATCH (c:Concept) WHERE elementId(c) = $eid CALL db.create.setNodeVectorProperty(c, 'type_vector', $vec) RETURN c", eid=node_eid, vec=type_vec)# ---------- 小規模測試:僅更新前N個Concept節點 ----------
def test_update_concepts_with_embeddings(sample_size=5):print(f"🔍 測試開始:選取前 {sample_size} 個 Concept 節點進行嵌入更新")with driver.session() as session:result = session.run("""MATCH (c:Concept)RETURN elementId(c) AS eid, c.name AS name, c.type AS typeLIMIT $limit""",limit=sample_size)for record in result:node_eid = record["eid"]name = record["name"]type_list = record["type"]type_str = ", ".join(type_list) if isinstance(type_list, list) else str(type_list)print(f"\n🧠 節點ID: {node_eid}")print(f"📌 名稱: {name}")print(f"📎 類型: {type_str}")name_vec = get_embedding(name)type_vec = get_embedding(type_str)if name_vec:print(f"? name_vector 維度: {len(name_vec)}")session.run("MATCH (c:Concept) WHERE elementId(c) = $eid CALL db.create.setNodeVectorProperty(c, 'name_vector', $vec) RETURN c", eid=node_eid, vec=name_vec)else:print("? 獲取 name_vector 失敗")if type_vec:print(f"? type_vector 維度: {len(type_vec)}")session.run("MATCH (c:Concept) WHERE elementId(c) = $eid CALL db.create.setNodeVectorProperty(c, 'type_vector', $vec) RETURN c", eid=node_eid, vec=type_vec)else:print("? 獲取 type_vector 失敗")print("? 測試完成,請前往 Neo4j Studio 檢查節點屬性是否正確更新。")# ---------- 創建向量索引(Neo4j 5+) ----------
def create_vector_index():vector_dim = 4096  # Qwen 模型返回向量維度為 4096with driver.session() as session:session.run(f"""CREATE VECTOR INDEX concept_name_vector_indexFOR (c:Concept) ON (c.name_vector)OPTIONS {{indexConfig: {{`vector.dimensions`: {vector_dim}, `vector.similarity_function`: 'cosine'}}}}""")session.run(f"""CREATE VECTOR INDEX concept_type_vector_indexFOR (c:Concept) ON (c.type_vector)OPTIONS {{indexConfig: {{`vector.dimensions`: {vector_dim}, `vector.similarity_function`: 'cosine'}}}}""")# ---------- 相似節點查詢函數 ----------
def query_similar_concepts(input_term):query_vec = get_embedding(input_term)if not query_vec:return []with driver.session() as session:try:result = session.run("""CALL db.index.vector.queryNodes('concept_name_vector_index', 3, $embedding)YIELD node, scoreWHERE score >= 0.8RETURN node.CUI AS cui, node.name AS name, scoreORDER BY score DESC""",embedding=query_vec)return result.data()except Exception as e:print("? 查詢失敗,請確認索引是否創建:", str(e))return []# ---------- 主程序入口 ----------
if __name__ == "__main__":# ? 創建索引(若首次運行)create_vector_index()# ? 測試模式:小批量處理# test_update_concepts_with_embeddings(sample_size=5)# ?? 正式運行時請取消注釋以下行# update_concepts_with_embeddings()# ? 查詢測試concept_results = query_similar_concepts("Retired procedure")for item in concept_results:print(f"CUI: {item['cui']}, 名稱: {item['name']}, 相似度: {item['score']:.4f}")

?

測試效果如下:

neo4j中向量也放上去了?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915529.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915529.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915529.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【AI深究】隨機森林(Random Forest)全網最詳細全流程詳解與案例(附Python代碼演示)|集成學習|數學原理、案例流程、代碼演示及結果解讀|參數與調優、工程啟示、單棵決策樹的對比、優缺點

大家好&#xff0c;我是愛醬。本篇將會系統地講解隨機森林&#xff08;Random Forest&#xff09;的原理、核心思想、數學表達、算法流程、代碼實現與工程應用。內容適合初學者和進階讀者&#xff0c;配合公式和可視化示例。 注&#xff1a;本文章含大量數學算式、詳細例子說明…

6.String、StringBuffer、StringBuilder區別及使用場景

String固定長度&#xff0c;引用的字符串內容無法改變例如&#xff0c;String s abc;s def;那么 s 字符串對應的地址已經改變了StringBuider 聲明一個對象時&#xff0c;指向堆中的一塊空間&#xff0c;包括兩個屬性 value 和 count其中 value 屬性類似動態數組&#xff0c;可…

Qualcomm Linux 藍牙指南學習--驗證 Fluoride 協議棧的功能(2)

前言 Qualcomm Technologies推出的Linux藍牙指南詳細介紹了基于Qualcomm RB3 Gen 2和IQ-9100 Beta開發套件的藍牙解決方案。該文檔涵蓋BlueZ和Fluoride協議棧的功能驗證流程,支持藍牙5.2核心規范,包括WCN6750/WCN6856/QCA6698AQ芯片組的特性。主要內容分為三部分: ?1. 功…

Spring Boot中REST與gRPC并存架構設計與性能優化實踐指南

Spring Boot中REST與gRPC并存架構設計與性能優化實踐指南 在微服務架構日益復雜的當下&#xff0c;單一協議往往難以滿足高并發低延遲與生態兼容的雙重需求。本文基于真實生產環境的項目經驗&#xff0c;分享了如何在Spring Boot中同時提供RESTful API和gRPC接口的架構設計、性…

Simulink仿真-model Setting關鍵配置

1.概述 Simulink 的仿真設置&#xff08;Model Settings&#xff09;是確保仿真準確性的關鍵配置&#xff0c;主要包括仿真時間、步長、解法器選擇等核心參數的設定。 ?可以通過快捷鍵?CtrlE?打開仿真設置界面2.核心參數 2.1 求解器Solver配置 時間范圍&#xff1a;設置仿真…

內網與外網是通過什么進行傳輸的?內外網文件傳輸的安全方法

在當前企業信息化建設日益深入的背景下&#xff0c;出于安全防護與合規管理的需要&#xff0c;很多單位將網絡劃分為內網&#xff08;辦公網/生產網&#xff09;與外網&#xff08;互聯網/DMZ區&#xff09;。這種網絡隔離策略雖然提升了安全性&#xff0c;但也帶來了內外網文件…

RabbitMQ面試精講 Day 4:Queue屬性與消息特性

【RabbitMQ面試精講 Day 4】Queue屬性與消息特性 開篇 歡迎來到"RabbitMQ面試精講"系列的第4天&#xff01;今天我們將深入探討RabbitMQ中Queue的屬性配置與消息特性&#xff0c;這是理解和優化RabbitMQ使用的關鍵知識點。掌握這些內容不僅能幫助你在面試中展現深厚…

uniapp vue3 vite項目使用微信云開發(云函數)

1、在根目錄新建文件夾 cloudfunctions2、配置 manifest.json在項目根目錄的 manifest.json 文件中&#xff0c;找到微信小程序配置部分&#xff0c;添加 cloudfunctionRoot 字段&#xff0c;指向你的云函數目錄&#xff1a;{"mp-weixin": {"cloudfunctionRoot&…

AK視頻下載工具:免費高效,多平臺支持

近期小編又發現了一款更強大的新神器——AK視頻下載&#xff08;電腦版&#xff09;&#xff0c;一起來了解下吧~ 軟件亮點 完全免費&#xff0c;無需安裝&#xff0c;操作便捷&#xff0c;直接打開即可使用。 支持多平臺視頻下載&#xff0c;包括抖音、B站、小紅書、快手等主…

7月21日星期一今日早報簡報微語報早讀

7月21日星期一&#xff0c;農歷六月廿七&#xff0c;早報#微語早讀。1、廣東佛山累計報告基孔肯雅熱確診病例1873例&#xff0c;均為輕癥&#xff1b;2、祝賀&#xff01;石宇奇奪得日本羽毛球公開賽男單冠軍&#xff1b;3、中國和匈牙利順利完成引渡條約談判&#xff1b;4、科…

基于Milvus Lite的輕量級向量數據庫實戰指南

一、為什么選擇Milvus Lite&#xff1f; 在人工智能和語義搜索應用中&#xff0c;高效的向量檢索是核心需求。相比需要部署Docker的完整版Milvus&#xff0c;Milvus Lite提供&#xff1a; 零依賴&#xff1a;純Python實現&#xff0c;無需安裝Docker或外部組件 開箱即用&…

深度學習時代下的社交媒體情感分析:方法、工具與未來挑戰

摘要&#xff1a;基于Yue等學者2019年發表的權威綜述&#xff0c;本文系統總結情感分析的技術框架、實戰資源與前沿方向&#xff0c;附Python代碼示例。 一、情感分析為何重要&#xff1f; 情感分析&#xff08;Sentiment Analysis&#xff09;旨在從文本中提取主觀態度&…

Spring Boot 3.0新特性全面解析與實戰應用

Spring Boot 3.0新特性全面解析與實戰應用 引言 Spring Boot 3.0作為Spring生態系統的一個重要里程碑&#xff0c;帶來了眾多令人興奮的新特性和改進。本文將深入解析Spring Boot 3.0的核心變化&#xff0c;并通過實戰示例展示如何在項目中應用這些新特性。 核心變化概覽 Java版…

C# sqlsugar 主子表 聯合顯示 LeftJoin

在C#中使用SqlSugar ORM進行Left Join操作是一種常見需求&#xff0c;尤其是在處理復雜數據庫查詢時。SqlSugar是一個輕量級、高性能的ORM框架&#xff0c;支持多種數據庫。下面是如何使用SqlSugar進行Left Join操作的示例。1. 安裝SqlSugar首先&#xff0c;確保你的項目中已經…

【ROS1】08-ROS通信機制——服務通信

目錄 一、概念 二、何時使用服務 三、話題通信與服務通信的區別 四、案例 4.1 C實現 4.1.1 服務端 4.1.2 客戶端 4.1.3 測試執行 4.2 Python實現 4.2.1 服務端 4.2.2 客戶端 4.2.3 客戶端優化——動態傳參 4.2.4 客戶端優化——等待服務端啟動后再發起請求 一、概…

45.sentinel自定義異常

上文提到Blocked by Sentinel(flow limits) 限流異常,這樣返給用戶就不太友好,所以需要自定義異常。 默認情況下,發生限流、降級、授權攔截時,都會拋出異常到調用方。如果要自定義異常時的返回結果,需要實現BlockExceptionHandler接口: BlockException有很多子類: pac…

f4硬件配置spi

f4型號是stm32f407zgt6用spi來進行MOSI&#xff0c;主機發送從機接收時鐘頻率設置為1MHzMOSI為PC3&#xff0c;SCK為PB10&#xff0c;CS設置為output->PB12時鐘配置如下&#xff1a;波特率計算公式為&#xff1a;128M/(4*Prescaler) 要讓波特率為1M&#xff0c;10…

Redis的持久化-RDB

1.持久化一提到持久化&#xff0c;我們就會第一時間聯想到M有SQL的事務&#xff0c;MySQL事務有四個比較核心的特征&#xff1a;原子性&#xff08;把多個操作打包成一個整體&#xff09;&#xff0c;一致性&#xff08;事務執行之前和之后&#xff0c;數據都不能離譜&#xff…

前端內存泄漏

個人簡介 &#x1f440;個人主頁&#xff1a; 前端雜貨鋪 &#x1f64b;?♂?學習方向&#xff1a; 主攻前端方向&#xff0c;正逐漸往全干發展 &#x1f4c3;個人狀態&#xff1a; 研發工程師&#xff0c;現效力于中國工業軟件事業 &#x1f680;人生格言&#xff1a; 積跬步…

部署zabbox企業級分布式監控

目錄 一、監控系統的基礎認知 2.1 監控的定義與核心價值 2.2 監控的五大類型與五層邏輯架構 &#xff08;1&#xff09;五大監控類型 &#xff08;2&#xff09;五層邏輯架構 2.3 主流開源監控產品對比 二、Zabbix 系統深度解析 3.1 Zabbix 的定位與發展歷程 3.2 Zabb…