Protege 构建知识图谱并接入 Neo4j 与前端可视化实战
本文记录了一个完整的教育领域知识图谱项目流程,从本体建模到图数据库存储,再到前端的可视化展示。主要涉及 Protégé、Neo4j、Python 数据处理以及 Vue+ECharts 技术栈。
工具准备
1. Protégé 安装
推荐使用版本:Protégé-5.5.0。安装后需熟悉基本操作,如创建本体、定义类与属性等。
2. Neo4j 安装
Neo4j 对 JDK 版本有一定要求,建议配置 JDK 11。若本地存在多个 Java 版本,需确保环境变量 JAVA_HOME 指向正确的版本,避免启动报错。
数据导入流程
1. 启动 Neo4j
在命令行输入以下命令启动控制台模式:
neo4j.bat console
启动成功后,访问浏览器中的 Neo4j Browser。
2. 格式转换(OWL 转 Turtle)
Protégé 导出的 .owl 文件通常需转换为 .turtle 格式才能被 Neo4j 高效读取。如果直接生成失败或文件大小为 0KB,可尝试使用命令行工具手动转换。
在项目目录下打开 PowerShell,执行以下指令(注意替换文件名):
java -jar rdf2rdf-1.0.1-2.3.1.jar creature.owl creature.turtle
转换完成后检查文件大小,非空即表示成功。
3. 导入 Neo4j
进入 Neo4j Browser,依次执行以下 Cypher 语句。
清除旧数据
MATCH (n) DETACH DELETE n;
初始化 RDF 插件配置
CALL n10s.graphconfig.init();
导入 RDF 数据 请根据实际路径修改文件地址:
CALL n10s.rdf.import.fetch("file:///E:/BaiduNetdiskDownload/owl 导入 neo4j/第一单元_test.turtle", "RDF/XML", {handleVocabUris: "IGNORE"})
验证数据 查询部分节点信息:
MATCH (n) WHERE n:`课名称` OR n:`知识元` RETURN n LIMIT 500;
查询关系类型:
MATCH ()-[r]->() RETURN DISTINCT type(r) AS relationshipType
清理 URI 前缀 导入后的节点 URI 可能包含冗长的命名空间前缀,可使用以下语句简化:
MATCH (n) SET n.uri = REPLACE(n.uri, 'http://www.semanticweb.org/florence/ontologies/2025/1/untitled-ontology-9#', '') RETURN n
导出 JSON 数据
为了在前端进行可视化,需要将图数据导出为 JSON 格式。这需要借助 APOC 库。
首先确认 APOC 是否安装成功:
RETURN apoc.version()
使用 apoc.export.json.query 导出指定范围的数据:
CALL apoc.export.json.query(
"MATCH (n) WHERE n:`课名称` OR n:`知识元` OPTIONAL MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 500",
"file:///E:/neo4j/neo4j-community-4.4.41/import/output_3.0.json",
{format: 'PLAIN'}
)
此步骤生成的原始 JSON 结构并不直接符合 ECharts 的 nodes 和 links 格式,需要进行清洗。
前端可视化处理
1. Python 数据清洗
Neo4j 导出的 JSON 包含大量嵌套信息,我们需要编写 Python 脚本将其转换为 ECharts 所需的扁平化结构。
以下是处理脚本示例,请注意修改输入输出路径:
import json
def convert_to_echarts_data(file_path):
# 加载 Neo4j 导出的 JSON 数据
with open(file_path, 'r', encoding='utf-8') as f:
neo4j_data = json.load(f)
# 初始化 ECharts 数据结构
echarts_data = {
"nodes": [],
"links": []
}
# 节点处理:用于去重和避免重复添加
node_map = {}
for item in neo4j_data:
# 处理主节点
node = item.get("n", None)
if node:
node_id = node.get("id")
node_labels = node.get("labels", [])
node_properties = node.get("properties", {})
node_name = node_properties.get("名称", node_properties.get("name", node_id))
node_uri = node_properties.get("uri", node_id)
if node_id not in node_map:
echarts_node = {
"id": node_id,
"name": node_name,
"category": node_labels[1] if len(node_labels) > 1 else "其他",
"value": node_uri,
"properties": node_properties
}
echarts_data["nodes"].append(echarts_node)
node_map[node_id] = echarts_node
# 处理关联节点
m_node = item.get("m", None)
if m_node:
node_id = m_node.get("id")
node_labels = m_node.get("labels", [])
node_properties = m_node.get("properties", {})
node_name = node_properties.get("名称", node_properties.get("name", node_id))
node_uri = node_properties.get("uri", node_id)
if node_id not in node_map:
echarts_node = {
"id": node_id,
"name": node_name,
"category": node_labels[1] if len(node_labels) > 1 else "其他",
"value": node_uri,
"properties": node_properties
}
echarts_data["nodes"].append(echarts_node)
node_map[node_id] = echarts_node
# 边处理
for item in neo4j_data:
relationship = item.get("r", None)
if relationship:
start_node = relationship.get("start")
end_node = relationship.get("end")
start_id = start_node.get("id")
end_id = end_node.get("id")
relationship_label = relationship.get("label")
echarts_link = {
"source": start_id,
"target": end_id,
"value": relationship_label
}
echarts_data["links"].append(echarts_link)
return echarts_data
if __name__ == "__main__":
input_file = r"<你的输入文件路径>"
output_file = "converted_data.json"
echarts_data = convert_to_echarts_data(input_file)
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(echarts_data, f, ensure_ascii=False, indent=4)
print(f"数据已成功转换并保存到 {output_file}")
转换后的数据将包含标准的 nodes 和 links 数组,可直接用于 ECharts 渲染。
2. 前端集成
最后一步是学习 Vue 框架结合 ECharts 实现交互。由于本项目聚焦于教育领域的知识图谱,可根据具体业务需求调整节点样式与交互逻辑。完成上述所有步骤后,即可形成自己的可视化知识图谱应用。


