from neo4j import GraphDatabase import pandas as pd import json class KnowledgeGraphQuerier: def __init__(self, uri, user, password): self.driver = GraphDatabase.driver(uri, auth=(user, password)) def close(self): self.driver.close() def get_node_name(self, node_types, properties): """根据节点类型和可用属性确定节点名称""" # 根据用户提供的信息,为不同类型的节点设置名称属性 priority_map = { "ProjectDivisionSet": ["name"], "ProjectDivisionItem": ["name"], "Quota": ["name"], "MainMaterial": ["name"], "Equipment": ["name"], "MaterialOrEquipment": ["name"], "CostSet": ["GUID"], "CostItem": ["id"], "FeeTableTemplateSet": ["name"], "FeeTableTemplateItem": ["name"], "FeeCollection": ["name"], "FeeScheduleSet": ["name"], "FeeScheduleItem": ["name"], "Fee": ["name"], "ProjectPropertySet": ["name"], "ProjectProperty": ["软件名称"], } # 默认优先级顺序(适用于未明确定义的节点类型) default_priority = ["名称", "项目名称", "费用名称", "工程名称", "id", "GUID", "序号", "编码", "代码"] # 确定使用哪个优先级列表 priority_list = None for node_type in node_types: if node_type in priority_map: priority_list = priority_map[node_type] break if not priority_list: priority_list = default_priority # 按优先级查找第一个存在的属性 for prop in priority_list: if prop in properties and properties[prop]: return properties[prop] # 如果没有找到任何匹配的属性,返回第一个非空属性 for prop, value in properties.items(): if value: return value return "无名称" def get_simple_hierarchy(self): """获取简洁的图谱层级结构""" # 首先获取所有节点和它们的名称 with self.driver.session() as session: result = session.run( """ MATCH (n) RETURN id(n) AS node_id, labels(n) AS node_types, properties(n) AS properties """ ) nodes = {} for record in result: node_id = record["node_id"] node_types = record["node_types"] properties = record["properties"] # 获取节点名称 name = self.get_node_name(node_types, properties) # 以第一个类型作为节点的主要类型 main_type = node_types[0] if node_types else "Unknown" nodes[node_id] = {"id": node_id, "type": main_type, "name": name, "children": []} # 获取节点之间的关系 with self.driver.session() as session: result = session.run( """ MATCH (a)-[r]->(b) RETURN id(a) AS source_id, type(r) AS relationship_type, id(b) AS target_id """ ) # 构建父子关系 for record in result: source_id = record["source_id"] target_id = record["target_id"] if source_id in nodes and target_id in nodes: nodes[source_id]["children"].append(target_id) # 找出根节点(没有父节点的节点) all_nodes = set(nodes.keys()) child_nodes = set() for node in nodes.values(): child_nodes.update(node["children"]) root_nodes = all_nodes - child_nodes # 构建层级结构 hierarchy = [] for root_id in root_nodes: hierarchy.append(self._build_simple_hierarchy(root_id, nodes)) # 如果没有根节点,则返回所有节点的平级结构 if not hierarchy: for node_id in nodes: node_info = nodes[node_id] hierarchy.append({node_info["type"]: node_info["name"]}) return hierarchy def _build_simple_hierarchy(self, node_id, nodes): """递归构建简洁的节点层级结构""" node = nodes[node_id] node_type = node["type"] node_name = node["name"] # 创建当前节点的键值对 result = {node_type: node_name} # 如果有子节点,递归处理 if node["children"]: children = [] for child_id in node["children"]: children.append(self._build_simple_hierarchy(child_id, nodes)) # 将子节点添加到当前节点下 result["children"] = children return result def main(): # 连接信息 uri = "bolt://172.20.0.145:7687" user = "neo4j" password = "password" querier = KnowledgeGraphQuerier(uri, user, password) try: # 获取简洁的图谱层级结构 print("正在构建简洁的图谱层级结构...") hierarchy = querier.get_simple_hierarchy() # 将层级结构保存为JSON文件 print("正在保存图谱层级结构到JSON文件...") with open("kg_simple_hierarchy.json", "w", encoding="utf-8") as f: json.dump(hierarchy, f, ensure_ascii=False, indent=2) print("简洁的图谱层级结构已保存到 kg_simple_hierarchy.json") finally: querier.close() if __name__ == "__main__": main()