在上一篇中我们利用大模型自身的能力来抽取文本中的关系,但是这些默认设置不是很准确。或者数据本身就存在数据库中,已经是结构化的(如 CSV、JSON),就是有逻辑和规律的数据,或者对节点和关系的产生有极其严格的业务逻辑要求,不希望依赖 LLMs 的随机性。那么,这时就可以其自身的特征来直接存入Neo4j图数据库中。
最关键的是要编写明确的 Cypher 语句(推荐用于生产环境、结构化数据)。
from langchain_neo4j import Neo4jGraph
import json
# 假设你的文本数据是一组结构化的实体关系描述
json_data = """
[
{"source": "张三", "source_type": "Person", "target": "阿里巴巴", "target_type": "Organization", "relation": "就职于", "since": "2020"},
{"source": "阿里巴巴", "source_type": "Organization", "target": "杭州", "target_type": "Location", "relation": "总部位于", "since": "1999"}
]
"""
data_list = json.loads(json_data)
graph = Neo4jGraph(url="bolt://localhost:7687", username="neo4j", password="password")
# 节点与关系的处理与写入(通过 Cypher 模版)
# 在 Neo4j 中,处理节点和关系的核心原则是 去重与合并 (MERGE)。如果使用 CREATE,每次运行都会创建重复的节点;而 MERGE 相当于 “存在则匹配,不存在则创建”。
# 我们可以利用 Neo4jGraph.query 方法,将数据作为参数传进去批量执行:
# 2.1 编写精细化的 Cypher 动态写入模板
# 注意:因为 Neo4j 标签(Label)和关系类型(Type)不能动态参数化,
# 建议在业务逻辑清晰时,针对不同的节点类型写不同的 Cypher,或者使用类似 APOC 的动态扩展。
cypher_query = """
UNWIND $data AS row
// 1. 处理源节点(去重创建)
MERGE (source:Entity {name: row.source})
ON CREATE SET source.type = row.source_type
// 2. 处理目标节点(去重创建)
MERGE (target:Entity {name: row.target})
ON CREATE SET target.type = row.target_type
// 3. 处理关系与动态属性 (这里为了兼容动态关系,使用 APOC 插件,若未装 APOC,关系名需固定)
CALL apoc.create.relationship(source, row.relation, {since: row.since}, target) YIELD rel
RETURN count(*)
"""
# 2.2 执行写入
graph.query(cypher_query, params={"data": data_list})
print("图谱数据导入成功!")
# 补充下,增加数据的cypher语句
graph.query(
"""
MERGE (m:Movie {title:'Top Gun'})
WITH m
UNWIND ['Tom Cruise', 'Val Kilmer', 'Anthony Edwards', 'Meg Ryan'] AS actor
MERGE (a:Actor {name:actor})
MERGE (a)-[:ACTED_IN]->(m)
"""
)
到Neo4j数据库中查看相关数据
Cypher语句的核心设计解析
UNWIND 展开机制:
数据中的 symptom、check 等字段是数组(如 ["紫绀", "胸痛"])。Cypher 无法直接把数组连向一个节点。我们使用 WITH row, d UNWIND row.symptom AS sym_name,将数组拍平循环,一条条地为每个症状创建节点并连线。
MERGE 保证幂等性:
比如“内科”这个科室,不仅“肺泡蛋白质沉积症”有,“感冒”也有。使用 MERGE (dept:Department {name: dept_name}) 可以确保整个数据库里只有一个名叫“内科”的节点,所有相关的疾病都会连向它。
关系语义化:
通过 -[:HAS_SYMPTOM]->、-[:NEED_CHECK]-> 明确了图谱中边的含义,这对于后续构建 GraphCypherQAChain 时,大模型理解和生成正确的 Cypher 提问至关重要。