使用 Oracle Autonomous Database 和 Property Graph 查询语言创建知识图
简介
本教程探讨了图形理论、知识图的概念,以及如何使用 Oracle Autonomous Database with Property Graph Query Language (PGQL) 来实施这些概念。它还解释了 Python 实现,用于使用 LLM 从文档中提取关系,并将其作为图形结构存储在 Oracle 中。
什么是图形?
图形是数学和计算机科学的一个领域,专注于建模对象之间的关系。图形包括:
-
垂直(节点):表示实体。
-
边(链接):表示实体之间的关系。
图形广泛用于在社交网络、语义网络、知识图等中表示数据结构。
什么是知识图谱?
知识图是基于图形表示的真实世界知识,其中:
-
节点表示实体,例如人员、地点、产品等。
-
边表示语义关系。例如,工作地点、部分或更多。
知识图谱可增强语义搜索、推荐系统和问题解答应用程序。
为什么要将 Oracle Autonomous Database 与 PGQL 结合使用?
Oracle 提供了一个完全托管的环境来存储和查询属性图形:
-
PGQL 类似 SQL,专为查询复杂的图形模式而设计。
-
Oracle Autonomous Database 支持原生使用属性图形功能运行图形查询,包括创建、查询和可视化。
-
与 LLM 集成可自动从非结构化数据(如 PDF)中提取图形结构。
与其他图形查询语言的比较
Oracle Autonomous Database with PGQL 与传统图形数据库的优势
目标
- 使用 Oracle Autonomous Database 和 PGQL 创建知识图。
Prerequisites
- 安装 Python
version 3.10
或更高版本和 Oracle Cloud Infrastructure 命令行界面 (OCI CLI)。
任务 1:安装 Python 软件包
Python 代码需要某些库才能使用 Oracle Cloud Infrastructure (OCI) Generative AI。运行以下命令以安装所需的 Python 软件包。可以从以下位置下载该文件:requirements.txt 。
pip install -r requirements.txt
任务 2:创建 Oracle Database 23ai(始终免费)
在本任务中,我们将学习如何在始终免费模式下预配 Oracle Database 23ai。此版本提供完全托管的环境,非常适合开发、测试和学习,且无需额外付费。
-
登录 OCI 控制台,导航到 Oracle Database 和 Autonomous Database ,然后单击创建 Autonomous Database 实例。
-
输入以下信息。
- 数据库名称:输入实例的标识名称。
- 工作量类型:根据您的需要选择数据仓库或事务处理。
- 区间:选择合适的区间来组织资源。
-
选择始终免费以确保实例是免费预配的。
-
为
ADMIN
用户创建安全密码,该密码将用于访问数据库。 -
查看设置,然后单击创建 Autonomous Database 。等待几分钟,让实例进行预配并可供使用。
如果您不熟悉连接到 Oracle Autonomous Database 的过程,请按照以下链接了解并正确配置代码。
注:您需要使用 Wallet 方法连接到 Python 代码内的数据库。
任务 3:下载并理解代码
Graph 的一个非常常见的用例是将其用作与 LLM 和知识库(如 PDF 文件)一起工作的组件之一。
我们将使用本教程:使用 OCI Generative AI 分析自然语言中的 PDF 文档作为我们的基础,该基础使用上述所有组件。但是,在本文档中,我们将重点介绍如何将 Oracle Database 23ai 与 Graph 一起使用。基本上,基本材料中的 Python 代码 (main.py
) 仅在使用 Oracle Database 23ai 的部分中进行修改。
以下是在此服务上执行的进程:
-
创建图表方案。
-
使用 LLM 提取实体和关系。
-
向 Oracle 中插入数据。
-
构建属性图形。
从以下位置下载与 Oracle Database 23ai 兼容的更新 Python 图形代码:main.py 。
-
create_knowledge_graph
:def create_knowledge_graph(chunks): cursor = oracle_conn.cursor() # Creates graph if it does not exist try: cursor.execute(f""" BEGIN EXECUTE IMMEDIATE ' CREATE PROPERTY GRAPH {GRAPH_NAME} VERTEX TABLES (ENTITIES KEY (ID) LABEL ENTITIES PROPERTIES (NAME)) EDGE TABLES (RELATIONS KEY (ID) SOURCE KEY (SOURCE_ID) REFERENCES ENTITIES(ID) DESTINATION KEY (TARGET_ID) REFERENCES ENTITIES(ID) LABEL RELATIONS PROPERTIES (RELATION_TYPE, SOURCE_TEXT)) '; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -55358 THEN -- ORA-55358: Graph already exists RAISE; END IF; END; """) print(f"🧠 Graph '{GRAPH_NAME}' created or already exists.") except Exception as e: print(f"[GRAPH ERROR] Failed to create graph: {e}") # Inserting vertices and edges into the tables for doc in chunks: text = doc.page_content source = doc.metadata.get("source", "unknown") if not text.strip(): continue prompt = f""" You are an expert in knowledge extraction. Given the following technical text: {text} Extract key entities and relationships in the format: - Entity1 -[RELATION]-> Entity2 Use UPPERCASE for RELATION types. Return 'NONE' if nothing found. """ try: response = llm_for_rag.invoke(prompt) result = response.content.strip() except Exception as e: print(f"[ERROR] Gen AI call error: {e}") continue if result.upper() == "NONE": continue triples = result.splitlines() for triple in triples: parts = triple.split("-[") if len(parts) != 2: continue right_part = parts[1].split("]->") if len(right_part) != 2: continue raw_relation, entity2 = right_part relation = re.sub(r'\W+', '_', raw_relation.strip().upper()) entity1 = parts[0].strip() entity2 = entity2.strip() try: # Insertion of entities (with existence check) cursor.execute("MERGE INTO ENTITIES e USING (SELECT :name AS NAME FROM dual) src ON (e.name = src.name) WHEN NOT MATCHED THEN INSERT (NAME) VALUES (:name)", [entity1, entity1]) cursor.execute("MERGE INTO ENTITIES e USING (SELECT :name AS NAME FROM dual) src ON (e.name = src.name) WHEN NOT MATCHED THEN INSERT (NAME) VALUES (:name)", [entity2, entity2]) # Retrieve the IDs cursor.execute("SELECT ID FROM ENTITIES WHERE NAME = :name", [entity1]) source_id = cursor.fetchone()[0] cursor.execute("SELECT ID FROM ENTITIES WHERE NAME = :name", [entity2]) target_id = cursor.fetchone()[0] # Create relations cursor.execute(""" INSERT INTO RELATIONS (SOURCE_ID, TARGET_ID, RELATION_TYPE, SOURCE_TEXT) VALUES (:src, :tgt, :rel, :txt) """, [source_id, target_id, relation, source]) print(f"✅ {entity1} -[{relation}]-> {entity2}") except Exception as e: print(f"[INSERT ERROR] {e}") oracle_conn.commit() cursor.close() print("💾 Knowledge graph updated.")
-
使用
CREATE PROPERTY GRAPH
创建图形方案,链接ENTITIES
(通告)和RELATIONS
(边)。 -
仅当新实体不存在时才使用
MERGE INTO
插入新实体(确保唯一性)。 -
LLM (Oracle Generative AI) 用于提取
Entity1 -[RELATION]-> Entity2.
格式的三倍 -
与 Oracle 的所有交互都通过
oracledb
和 PL/SQL 匿名块完成。
现在,您可以:
-
使用 PGQL 浏览和查询图形关系。
-
连接到 Graph Studio 以实现可视化。
-
通过 API REST 或 LangChain 代理公开图形。
-
-
图形查询支持功能
有两个基本功能可以对知识图进行语义搜索和推理:
extract_graph_keywords
和query_knowledge_graph
。通过这些组件,可以在 Oracle Autonomous Database 上使用 PGQL 将问题解释为有意义的图形查询。-
extract_graph_keywords
:def extract_graph_keywords(question: str) -> str: prompt = f""" Based on the question below, extract relevant keywords (1 to 2 words per term) that can be used to search for entities and relationships in a technical knowledge graph. Question: "{question}" Rules: - Split compound terms (e.g., "API Gateway" → "API", "Gateway") - Remove duplicates - Do not include generic words such as: "what", "how", "the", "of", "in the document", etc. - Return only the keywords, separated by commas. No explanations. Result: """ try: resp = llm_for_rag.invoke(prompt) keywords_raw = resp.content.strip() # Additional post-processing: remove duplicates, normalize keywords = {kw.strip().lower() for kw in re.split(r'[,\n]+', keywords_raw)} keywords = [kw for kw in keywords if kw] # remove empty strings return ", ".join(sorted(keywords)) except Exception as e: print(f"[KEYWORD EXTRACTION ERROR] {e}") return ""
功能:
-
使用 LLM (
llm_for_rag
) 将自然语言问题转换为图形友好的关键字列表。 -
提示旨在清晰地提取与搜索图形相关的实体和术语。
为什么这很重要:
-
它弥合了非结构化问题和结构化查询之间的差距。
-
确保在 PGQL 查询中仅使用与域相关的特定术语进行匹配。
LLM 增强的行为:
-
打破复合技术术语。
-
删除停止词(例如 what 、 how 等)。
-
通过减少和删除重复项来规范化文本。
示例:
-
输入:
"What are the main components of an API Gateway architecture?"
-
输出关键字:
api, gateway, architecture, components
-
-
query_knowledge_graph
:def query_knowledge_graph(query_text): cursor = oracle_conn.cursor() sanitized_text = query_text.lower() pgql = f""" SELECT from_entity, relation_type, to_entity FROM GRAPH_TABLE( {GRAPH_NAME} MATCH (e1 is ENTITIES)-[r is RELATIONS]->(e2 is ENTITIES) WHERE CONTAINS(e1.name, '{sanitized_text}') > 0 OR CONTAINS(e2.name, '{sanitized_text}') > 0 OR CONTAINS(r.RELATION_TYPE, '{sanitized_text}') > 0 COLUMNS ( e1.name AS from_entity, r.RELATION_TYPE AS relation_type, e2.name AS to_entity ) ) FETCH FIRST 20 ROWS ONLY """ print(pgql) try: cursor.execute(pgql) rows = cursor.fetchall() if not rows: return "⚠️ No relationships found in the graph." return "\n".join(f"{r[0]} -[{r[1]}]-> {r[2]}" for r in rows) except Exception as e: return f"[PGQL ERROR] {e}" finally: cursor.close()
功能:
- 接受基于关键字的字符串(通常由
extract_graph_keywords
生成),并构建 PGQL 查询以从知识图中检索关系。
关键机制:
-
GRAPH_TABLE
子句使用MATCH
将图形从源节点遍历到目标节点。 -
它使用
CONTAINS()
允许在节点/边缘属性(e1.name
、e2.name
、r.RELATION_TYPE
)中进行部分和模糊搜索。 -
将结果限制为 20,以避免输出溢出。
为什么使用 PGQL:
-
PGQL 类似 SQL,但设计用于图形遍历。
-
Oracle Autonomous Database 支持属性图形,可实现关系和图形世界之间的无缝集成。
-
提供企业就绪的索引、优化和原生图形搜索功能。
Oracle 专用说明:
-
GRAPH_TABLE()
对 Oracle PGQL 是唯一的,它允许对通过关系表定义的图形的逻辑视图进行查询。 -
与 Cypher(Neo4j) 不同,PGQL 使用 SQL 扩展运行结构化数据,使其在 RDBMS 繁重的环境中更友好。
- 接受基于关键字的字符串(通常由
-
任务 4:运行聊天机器人
运行以下命令以运行聊天机器人。
python main.py
相关链接
确认
- 作者 — Cristiano Hoshikawa(Oracle LAD A,团队解决方案工程师)
更多学习资源
通过 docs.oracle.com/learn 浏览其他实验室,或者通过 Oracle Learning YouTube 频道访问更多免费学习内容。此外,请访问 education.oracle.com/learning-explorer 以成为 Oracle Learning Explorer。
有关产品文档,请访问 Oracle 帮助中心。
Create a Knowledge Graph with Oracle Autonomous Database and Property Graph Query Language
G38839-02
Copyright ©2025, Oracle and/or its affiliates.