parent
6ae9fd4d6e
commit
e5b714df41
Binary file not shown.
Binary file not shown.
@ -0,0 +1,12 @@
|
|||||||
|
from Config.Config import *
|
||||||
|
from Neo4j.Neo4jExecutor import *
|
||||||
|
|
||||||
|
# 使用示例
|
||||||
|
if __name__ == '__main__':
|
||||||
|
executor = Neo4jExecutor(
|
||||||
|
uri=NEO4J_URI,
|
||||||
|
auth=NEO4J_AUTH
|
||||||
|
)
|
||||||
|
# 清库
|
||||||
|
clear(executor.graph)
|
||||||
|
print("清库成功")
|
@ -0,0 +1,61 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from Neo4j.Neo4jExecutor import *
|
||||||
|
|
||||||
|
def json_to_cypher(data):
|
||||||
|
"""将知识体系JSON转换为Cypher插入脚本"""
|
||||||
|
cypher = []
|
||||||
|
seen = set()
|
||||||
|
|
||||||
|
def process_node(node, parent_id=None):
|
||||||
|
nonlocal seen
|
||||||
|
|
||||||
|
node_id = node['value']
|
||||||
|
node_name = node['title'].replace("'", "''")
|
||||||
|
|
||||||
|
# 创建当前节点
|
||||||
|
if node_id not in seen:
|
||||||
|
cypher.append(f"MERGE (n:KnowledgePoint {{id: '{node_id}'}}) SET n.name = '{node_name}';")
|
||||||
|
seen.add(node_id)
|
||||||
|
|
||||||
|
# 创建父子关系
|
||||||
|
if parent_id:
|
||||||
|
cypher.append(f"""
|
||||||
|
MATCH (parent:KnowledgePoint {{id: '{parent_id}'}}),
|
||||||
|
(child:KnowledgePoint {{id: '{node_id}'}})
|
||||||
|
MERGE (parent)-[:HAS_SUB_POINT]->(child);""")
|
||||||
|
|
||||||
|
# 递归处理子节点
|
||||||
|
if 'children' in node and not node['isLeaf']:
|
||||||
|
for child in node['children']:
|
||||||
|
process_node(child, parent_id=node_id)
|
||||||
|
|
||||||
|
# 处理根节点
|
||||||
|
for root in data['data']['tree']:
|
||||||
|
process_node(root)
|
||||||
|
|
||||||
|
# 处理根节点的父级关系(如果有)
|
||||||
|
if root.get('parentValue'):
|
||||||
|
cypher.append(f"MERGE (parent:KnowledgePoint {{id: '{root['parentValue']}'}});")
|
||||||
|
cypher.append(f"""
|
||||||
|
MATCH (parent:KnowledgePoint {{id: '{root['parentValue']}'}}),
|
||||||
|
(child:KnowledgePoint {{id: '{root['value']}'}})
|
||||||
|
MERGE (parent)-[:HAS_SUB_POINT]->(child);""")
|
||||||
|
|
||||||
|
return '\n'.join(cypher)
|
||||||
|
|
||||||
|
|
||||||
|
# 使用示例
|
||||||
|
if __name__ == '__main__':
|
||||||
|
executor = Neo4jExecutor(
|
||||||
|
uri=NEO4J_URI,
|
||||||
|
auth=NEO4J_AUTH
|
||||||
|
)
|
||||||
|
# 清库
|
||||||
|
clear(executor.graph)
|
||||||
|
|
||||||
|
# 这里替换成你的JSON数据变量
|
||||||
|
with open('小学数学知识点体系.json', 'r',encoding='utf-8') as f:
|
||||||
|
your_json_data = json.load(f)
|
||||||
|
cypherText=json_to_cypher(your_json_data)
|
||||||
|
executor.execute_cypher_text(cypherText)
|
@ -0,0 +1,61 @@
|
|||||||
|
from py2neo import Graph
|
||||||
|
import json
|
||||||
|
from Config import *
|
||||||
|
|
||||||
|
def query_all_questions():
|
||||||
|
# Neo4j连接配置
|
||||||
|
neo4j_config = {
|
||||||
|
"uri": NEO4J_URI, # 从Config导入
|
||||||
|
"auth": NEO4J_AUTH # 从Config导入
|
||||||
|
}
|
||||||
|
|
||||||
|
# 初始化图数据库连接
|
||||||
|
graph = Graph(**neo4j_config)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 获取所有试题ID
|
||||||
|
question_ids = graph.run(
|
||||||
|
"MATCH (q:Question) RETURN q.id AS question_id"
|
||||||
|
).data()
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
# 遍历每个试题
|
||||||
|
for record in question_ids:
|
||||||
|
qid = record['question_id']
|
||||||
|
# 修改查询部分
|
||||||
|
data = graph.run("""
|
||||||
|
MATCH (q:Question {id: $qid})
|
||||||
|
OPTIONAL MATCH (q)-[:REQUIRES_KNOWLEDGE]->(kp:KnowledgePoint)
|
||||||
|
OPTIONAL MATCH (q)-[:DEVELOPS_LITERACY]->(lp:LiteracyNode)
|
||||||
|
RETURN
|
||||||
|
q.content AS content,
|
||||||
|
collect(DISTINCT {id: kp.id, name: kp.name}) AS knowledge_points,
|
||||||
|
collect(DISTINCT {id: lp.value, title: lp.title}) AS literacy_points
|
||||||
|
""", qid=qid).data()
|
||||||
|
|
||||||
|
if data:
|
||||||
|
result = {
|
||||||
|
"question_id": qid,
|
||||||
|
"content": data[0]['content'],
|
||||||
|
"knowledge_points": data[0]['knowledge_points'],
|
||||||
|
"literacy_points": data[0]['literacy_points']
|
||||||
|
}
|
||||||
|
results.append(result)
|
||||||
|
|
||||||
|
# 增强版输出展示
|
||||||
|
print(f"\n{'=' * 40} 题目详情 {'=' * 40}")
|
||||||
|
print(f"📚 试题ID: {qid}")
|
||||||
|
print(f"📝 内容全文: {result['content']}") # 新增完整内容输出
|
||||||
|
print(f"🔍 内容摘要: {result['content'][:50]}...") # 保留摘要显示
|
||||||
|
print(f"🧠 知识点: {[kp['name'] for kp in result['knowledge_points']]}")
|
||||||
|
print(f"🆔 知识点ID: {[kp['id'] for kp in result['knowledge_points']]}")
|
||||||
|
print(f"🌟 素养点: {[lp['title'] for lp in result['literacy_points']]}")
|
||||||
|
print(f"🔢 素养点ID: {[lp['id'] for lp in result['literacy_points']]}")
|
||||||
|
print('=' * 90)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 查询失败: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
query_all_questions()
|
@ -0,0 +1,107 @@
|
|||||||
|
import re
|
||||||
|
from Config import *
|
||||||
|
from py2neo import Graph, Node, Relationship, Subgraph
|
||||||
|
from typing import List, Tuple
|
||||||
|
|
||||||
|
def clear(db):
|
||||||
|
# 清空数据
|
||||||
|
db.run("MATCH (n) DETACH DELETE n")
|
||||||
|
|
||||||
|
# 分步删除约束和索引
|
||||||
|
try:
|
||||||
|
# 删除约束
|
||||||
|
constraints = db.run("SHOW CONSTRAINTS YIELD name").data()
|
||||||
|
for constr in constraints:
|
||||||
|
db.run(f"DROP CONSTRAINT `{constr['name']}`")
|
||||||
|
|
||||||
|
# 删除索引
|
||||||
|
indexes = db.run("SHOW INDEXES YIELD name, type WHERE type <> 'LOOKUP'").data()
|
||||||
|
for idx in indexes:
|
||||||
|
db.run(f"DROP INDEX `{idx['name']}`")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"删除操作失败: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
def create_subgraph(db: Graph, nodes: List[Node], relations: List[Tuple[Node, str, Node]]) -> None:
|
||||||
|
"""统一创建子图"""
|
||||||
|
subgraph = Subgraph(
|
||||||
|
nodes=nodes,
|
||||||
|
relationships=[Relationship(start, rel_type, end) for start, rel_type, end in relations]
|
||||||
|
)
|
||||||
|
db.create(subgraph)
|
||||||
|
|
||||||
|
def tx_create(db: Graph, nodes: List[Node], relations: List[Tuple[Node, str, Node]]) -> None:
|
||||||
|
"""事务方式创建数据"""
|
||||||
|
try:
|
||||||
|
tx = db.begin()
|
||||||
|
subgraph = Subgraph(
|
||||||
|
nodes=nodes,
|
||||||
|
relationships=[Relationship(start, rel_type, end) for start, rel_type, end in relations]
|
||||||
|
)
|
||||||
|
tx.create(subgraph)
|
||||||
|
db.commit(tx)
|
||||||
|
except Exception as e:
|
||||||
|
db.rollback(tx)
|
||||||
|
print(f"事务操作失败: {str(e)}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
class Neo4jExecutor:
|
||||||
|
def __init__(self, uri, auth):
|
||||||
|
self.graph = Graph(uri, auth=auth)
|
||||||
|
|
||||||
|
# 新增文本执行方法
|
||||||
|
def execute_cypher_text(self, cypher_text: str) -> dict:
|
||||||
|
"""直接执行Cypher文本"""
|
||||||
|
stats = {'total': 0, 'success': 0, 'failed': 0}
|
||||||
|
try:
|
||||||
|
statements = re.split(r';\s*\n', cypher_text)
|
||||||
|
statements = [s.strip() for s in statements if s.strip()]
|
||||||
|
|
||||||
|
stats['total'] = len(statements)
|
||||||
|
|
||||||
|
for stmt in statements:
|
||||||
|
try:
|
||||||
|
self.graph.run(stmt)
|
||||||
|
stats['success'] += 1
|
||||||
|
except Exception as e:
|
||||||
|
stats['failed'] += 1
|
||||||
|
print(f"执行失败: {stmt[:50]}... \n错误: {str(e)[:100]}")
|
||||||
|
|
||||||
|
return stats
|
||||||
|
except Exception as e:
|
||||||
|
print(f"执行失败: {stmt[:100]}... \n完整错误: {str(e)}") # 原为str(e)[:100]
|
||||||
|
return stats
|
||||||
|
|
||||||
|
def execute_cypher_file(self, file_path: str) -> dict: # 确保方法名称正确
|
||||||
|
"""执行Cypher文件"""
|
||||||
|
stats = {'total': 0, 'success': 0, 'failed': 0}
|
||||||
|
try:
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as f:
|
||||||
|
cypher_script = f.read()
|
||||||
|
statements = re.split(r';\s*\n', cypher_script)
|
||||||
|
statements = [s.strip() for s in statements if s.strip()]
|
||||||
|
|
||||||
|
stats['total'] = len(statements)
|
||||||
|
|
||||||
|
for stmt in statements:
|
||||||
|
try:
|
||||||
|
self.graph.run(stmt)
|
||||||
|
stats['success'] += 1
|
||||||
|
except Exception as e:
|
||||||
|
stats['failed'] += 1
|
||||||
|
print(f"执行失败: {stmt[:50]}... \n错误: {str(e)[:100]}")
|
||||||
|
|
||||||
|
return stats
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"文件错误: {str(e)}")
|
||||||
|
return stats
|
||||||
|
|
||||||
|
|
||||||
|
def init():
|
||||||
|
executor = Neo4jExecutor(
|
||||||
|
uri=NEO4J_URI,
|
||||||
|
auth=NEO4J_AUTH
|
||||||
|
)
|
||||||
|
# 清库
|
||||||
|
clear(executor.graph)
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue