Browse Source

all

yangrongze
hanyuqing 3 months ago
parent
commit
946a67f557
  1. 10
      controller/QAController.py
  2. 87
      util/neo4j_utils.py
  3. 13
      vue/src/router/index.js
  4. 17
      vue/src/system/GraphQA.vue

10
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),

87
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,

13
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({

17
vue/src/system/GraphQA.vue

@ -0,0 +1,17 @@
<template>
<div style="display: flex;
height: 100vh;">
<Menu
:initial-active="2"
/>
</div>
</template>
<script setup>
import Menu from "@/components/Menu.vue";
</script>
<style scoped>
</style>
Loading…
Cancel
Save