package service import ( "context" "fmt" "github.com/neo4j/neo4j-go-driver/v5/neo4j" "knowledge-graph-backend/internal/model" ) func (s *Neo4jService) GetGraphData() model.GraphData { ctx := context.Background() var nodes []model.Node var edges []model.Edge nodeResult, err := neo4j.ExecuteQuery(ctx, s.driver, "MATCH (n) RETURN n", map[string]any{}, neo4j.EagerResultTransformer, ) if err != nil { fmt.Printf("Error querying nodes: %v\n", err) return model.GraphData{} } for _, record := range nodeResult.Records { if v, ok := record.Get("n"); ok { if n, ok := v.(neo4j.Node); ok { nodes = append(nodes, neo4jNodeToModel(n)) } } } edgeResult, err := neo4j.ExecuteQuery(ctx, s.driver, "MATCH (a)-[r]->(b) RETURN a.id AS source, b.id AS target, r", map[string]any{}, neo4j.EagerResultTransformer, ) if err != nil { fmt.Printf("Error querying edges: %v\n", err) return model.GraphData{Nodes: nodes} } for _, record := range edgeResult.Records { source, _ := record.Get("source") target, _ := record.Get("target") v, _ := record.Get("r") if rel, ok := v.(neo4j.Relationship); ok { edge := neo4jRelToModel(rel) if s, ok := source.(string); ok { edge.Source = s } if t, ok := target.(string); ok { edge.Target = t } edges = append(edges, edge) } } return model.GraphData{Nodes: nodes, Edges: edges} } func (s *Neo4jService) GetNodeByID(id string) (model.Node, bool) { node, found, err := s.fetchNodeByID(id) if err != nil || !found { return model.Node{}, false } return node, true } func (s *Neo4jService) SearchNodes(query string) []model.Node { if query == "" { return []model.Node{} } ctx := context.Background() result, err := neo4j.ExecuteQuery(ctx, s.driver, `MATCH (n) WHERE toLower(n.label) CONTAINS toLower($query) OR toLower(n.id) CONTAINS toLower($query) OR (n.type IS NOT NULL AND toLower(n.type) CONTAINS toLower($query)) RETURN n`, map[string]any{"query": query}, neo4j.EagerResultTransformer, ) if err != nil { return []model.Node{} } var nodes []model.Node for _, record := range result.Records { v, _ := record.Get("n") if n, ok := v.(neo4j.Node); ok { nodes = append(nodes, neo4jNodeToModel(n)) } } return nodes } func (s *Neo4jService) GetNeighbors(nodeID string) (model.NeighborResponse, bool) { ctx := context.Background() if _, exists := s.GetNodeByID(nodeID); !exists { return model.NeighborResponse{}, false } result, err := neo4j.ExecuteQuery(ctx, s.driver, `MATCH ({id: $id})-[r]-(m) RETURN m, r, startNode(r).id AS source, endNode(r).id AS target`, map[string]any{"id": nodeID}, neo4j.EagerResultTransformer, ) if err != nil { return model.NeighborResponse{Nodes: []model.Node{}, Edges: []model.Edge{}}, true } neighborMap := make(map[string]model.Node) edgeMap := make(map[string]model.Edge) for _, record := range result.Records { if v, ok := record.Get("m"); ok { if n, ok := v.(neo4j.Node); ok { modelNode := neo4jNodeToModel(n) neighborMap[modelNode.ID] = modelNode } } if v, ok := record.Get("r"); ok { if rel, ok := v.(neo4j.Relationship); ok { edge := neo4jRelToModel(rel) if source, ok := record.Get("source"); ok { if s, ok := source.(string); ok { edge.Source = s } } if target, ok := record.Get("target"); ok { if t, ok := target.(string); ok { edge.Target = t } } edgeMap[edge.ID] = edge } } } var neighborNodes []model.Node for _, n := range neighborMap { neighborNodes = append(neighborNodes, n) } var relatedEdges []model.Edge for _, e := range edgeMap { relatedEdges = append(relatedEdges, e) } return model.NeighborResponse{Nodes: neighborNodes, Edges: relatedEdges}, true } func (s *Neo4jService) GetStats() map[string]int { ctx := context.Background() result, err := neo4j.ExecuteQuery(ctx, s.driver, `MATCH (n) RETURN count(n) AS totalNodes, sum(CASE WHEN n.type = '概念' THEN 1 ELSE 0 END) AS conceptNodes, sum(CASE WHEN n.type = '工具' THEN 1 ELSE 0 END) AS toolNodes, sum(CASE WHEN n.type = '应用' THEN 1 ELSE 0 END) AS applicationNodes`, map[string]any{}, neo4j.EagerResultTransformer, ) if err != nil || len(result.Records) == 0 { return map[string]int{} } record := result.Records[0] totalNodes := getInt(record, "totalNodes") conceptNodes := getInt(record, "conceptNodes") toolNodes := getInt(record, "toolNodes") applicationNodes := getInt(record, "applicationNodes") totalEdges := 0 edgeResult, err := neo4j.ExecuteQuery(ctx, s.driver, "MATCH ()-[r]->() RETURN count(r) AS totalEdges", map[string]any{}, neo4j.EagerResultTransformer, ) if err == nil && len(edgeResult.Records) > 0 { totalEdges = getInt(edgeResult.Records[0], "totalEdges") } return map[string]int{ "totalNodes": totalNodes, "totalEdges": totalEdges, "conceptNodes": conceptNodes, "toolNodes": toolNodes, "applicationNodes": applicationNodes, } }