diff --git a/controller/QAController.py b/controller/QAController.py index 7855cdf..d258850 100644 --- a/controller/QAController.py +++ b/controller/QAController.py @@ -1,6 +1,6 @@ import json import traceback - +from util.neo4j_utils import Neo4jUtil, neo4j_client import httpx from robyn import jsonify, Response @@ -27,6 +27,14 @@ async def analyze(request): resp_json_data = resp_json.get("data",{}) resp_json_data = json.loads(resp_json_data) entities = resp_json_data.get("entities", []) + print(entities) + for name in entities: + Neo4jUtil.find_neighbors_with_relationships( + node_label=None, + direction="both", + node_properties={"name": name}, + ) + return Response( status_code=200, description=jsonify(entities), diff --git a/util/neo4j_utils.py b/util/neo4j_utils.py index 79b5206..78386cf 100644 --- a/util/neo4j_utils.py +++ b/util/neo4j_utils.py @@ -205,6 +205,93 @@ class Neo4jUtil: raw = self.execute_read(cypher) return [self._enrich_relationship(row) for row in raw] + def find_neighbors_with_relationshipsAI( + self, + node_label: Optional[str], + node_properties: Dict[str, Any], + direction: str = "both", + rel_type: Optional[str] = None, + ) -> Dict[str, List[Dict[str, Any]]]: + """ + 查询指定节点的所有邻居,返回扁平化的 nodes 和 relationships(无数量限制) + """ + if not node_properties: + raise ValueError("node_properties 不能为空,用于定位起始节点") + + where_clause, params = self._build_where_conditions("n", node_properties, "node") + rel_filter = f":`{rel_type}`" if rel_type else "" + + if node_label is not None: + node_pattern = f"(n:`{node_label}`)" + else: + node_pattern = "(n)" + + if direction == "out": + pattern = f"{node_pattern}-[r{rel_filter}]->(m)" + elif direction == "in": + pattern = f"{node_pattern}<[r{rel_filter}]-(m)" + elif direction == "both": + pattern = f"{node_pattern}-[r{rel_filter}]-(m)" + else: + raise ValueError("direction 必须是 'out', 'in' 或 'both'") + + cypher = f""" + MATCH {pattern} + WHERE {where_clause} + WITH r, startNode(r) AS s, endNode(r) AS t + RETURN + elementId(s) AS sourceId, + head(labels(s)) AS sourceLabel, + s{{.*}} AS sourceProps, + + elementId(t) AS targetId, + head(labels(t)) AS targetLabel, + t{{.*}} AS targetProps, + + elementId(r) AS relId, + type(r) AS relType, + r{{.*}} AS relProps + """ + + try: + raw_results = self.execute_read(cypher, params) + except Exception as e: + traceback.print_exc() + raise RuntimeError(f"查询邻居节点时发生数据库错误: {str(e)}") from e + + # 用字典去重节点(key 为 id) + node_dict = {} + relationships = [] + + for row in raw_results: + # 处理 source 节点 + source_id = row["sourceId"] + if source_id not in node_dict: + source_node = dict(row["sourceProps"]) + source_node.update({"id": source_id, "label": row["sourceLabel"]}) + node_dict[source_id] = source_node + + # 处理 target 节点 + target_id = row["targetId"] + if target_id not in node_dict: + target_node = dict(row["targetProps"]) + target_node.update({"id": target_id, "label": row["targetLabel"]}) + node_dict[target_id] = target_node + + # 处理 relationship + rel = { + "id": row["relId"], + "type": row["relType"], + "sourceId": source_id, + "targetId": target_id, + "properties": dict(row["relProps"]) if row["relProps"] else {} + } + relationships.append(rel) + + return { + "nodes": list(node_dict.values()), + "relationships": relationships + } def find_relationships_by_condition( self, source_label: Optional[str] = None, diff --git a/vue/src/router/index.js b/vue/src/router/index.js index 71eb23b..406d92d 100644 --- a/vue/src/router/index.js +++ b/vue/src/router/index.js @@ -5,6 +5,7 @@ import Profile from '../system/Profile.vue' import Display from '../system/GraphDemo.vue' import Builder from '../system/GraphBuilder.vue' import Style from '../system/GraphStyle.vue' +import QA from '../system/GraphQA.vue' const routes = [ { path: '/', @@ -41,6 +42,18 @@ const routes = [ name: 'Style', component: Style } + , + { + path: '/kg-style', + name: 'Style', + component: Style + }, + + { + path: '/kg-qa', + name: 'QA', + component: QA + } ] const router = createRouter({ diff --git a/vue/src/system/GraphQA.vue b/vue/src/system/GraphQA.vue new file mode 100644 index 0000000..254f596 --- /dev/null +++ b/vue/src/system/GraphQA.vue @@ -0,0 +1,17 @@ + + + + \ No newline at end of file