From 8c5cd3705ab268f6e0ecbd9bfd9de074b04970b1 Mon Sep 17 00:00:00 2001 From: wonder Date: Wed, 15 Apr 2026 14:52:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=AE=80=E5=8C=96?= =?UTF-8?q?=E7=89=88json=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 4 +- backend/docs/docs.go | 78 +++++++++++++++++++++++++++++++ backend/docs/swagger.json | 78 +++++++++++++++++++++++++++++++ backend/docs/swagger.yaml | 53 +++++++++++++++++++++ backend/handlers/graph_handler.go | 11 +++++ backend/main.go | 2 + backend/models/graph.go | 21 +++++++++ backend/services/neo4j_service.go | 63 +++++++++++++++++++++++++ backend/services/service.go | 1 + 9 files changed, 310 insertions(+), 1 deletion(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 7d76490..878b4b6 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -3,7 +3,9 @@ "allow": [ "Bash(curl -X POST \"http://localhost:3001/api/nodes\" -H \"Content-Type: application/json\" -d \"{\\\\\"id\\\\\":\\\\\"test_node_1\\\\\",\\\\\"label\\\\\":\\\\\"测试节点\\\\\",\\\\\"type\\\\\":\\\\\"测试类型\\\\\",\\\\\"x\\\\\":100,\\\\\"y\\\\\":200}\" -s)", "Bash(curl -X PUT \"http://localhost:3001/api/nodes/test_node_1\" -H \"Content-Type: application/json\" -d \"{\\\\\"label\\\\\":\\\\\"更新后的测试节点\\\\\",\\\\\"x\\\\\":150}\" -s)", - "Bash(curl:*)" + "Bash(curl:*)", + "Bash(~/go/bin/swag init:*)", + "Bash(go run:*)" ] } } diff --git a/backend/docs/docs.go b/backend/docs/docs.go index ffe91fb..216b307 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go @@ -131,6 +131,29 @@ const docTemplate = `{ } } }, + "/api/graph/simpleJson": { + "get": { + "description": "获取知识图谱的全部节点和边数据(仅保留核心信息,适合LLM处理)", + "produces": [ + "application/json" + ], + "summary": "获取简化图数据", + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/models.SimpleGraphData" + } + }, + "500": { + "description": "内部错误", + "schema": { + "$ref": "#/definitions/models.ErrorResponse" + } + } + } + } + }, "/api/graph/stats": { "get": { "description": "获取知识图谱的节点数、边数等统计信息", @@ -694,6 +717,61 @@ const docTemplate = `{ } } }, + "models.SimpleEdge": { + "type": "object", + "properties": { + "label": { + "type": "string", + "example": "包含" + }, + "source": { + "type": "string", + "example": "1" + }, + "target": { + "type": "string", + "example": "2" + }, + "type": { + "type": "string", + "example": "CONTAINS" + } + } + }, + "models.SimpleGraphData": { + "type": "object", + "properties": { + "edges": { + "type": "array", + "items": { + "$ref": "#/definitions/models.SimpleEdge" + } + }, + "nodes": { + "type": "array", + "items": { + "$ref": "#/definitions/models.SimpleNode" + } + } + } + }, + "models.SimpleNode": { + "type": "object", + "properties": { + "id": { + "type": "string", + "example": "1" + }, + "label": { + "type": "string", + "example": "人工智能" + }, + "type": { + "type": "string", + "example": "概念" + } + } + }, "models.UpdateNodeRequest": { "type": "object", "properties": { diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 4cc1b73..4170c45 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -125,6 +125,29 @@ } } }, + "/api/graph/simpleJson": { + "get": { + "description": "获取知识图谱的全部节点和边数据(仅保留核心信息,适合LLM处理)", + "produces": [ + "application/json" + ], + "summary": "获取简化图数据", + "responses": { + "200": { + "description": "成功", + "schema": { + "$ref": "#/definitions/models.SimpleGraphData" + } + }, + "500": { + "description": "内部错误", + "schema": { + "$ref": "#/definitions/models.ErrorResponse" + } + } + } + } + }, "/api/graph/stats": { "get": { "description": "获取知识图谱的节点数、边数等统计信息", @@ -688,6 +711,61 @@ } } }, + "models.SimpleEdge": { + "type": "object", + "properties": { + "label": { + "type": "string", + "example": "包含" + }, + "source": { + "type": "string", + "example": "1" + }, + "target": { + "type": "string", + "example": "2" + }, + "type": { + "type": "string", + "example": "CONTAINS" + } + } + }, + "models.SimpleGraphData": { + "type": "object", + "properties": { + "edges": { + "type": "array", + "items": { + "$ref": "#/definitions/models.SimpleEdge" + } + }, + "nodes": { + "type": "array", + "items": { + "$ref": "#/definitions/models.SimpleNode" + } + } + } + }, + "models.SimpleNode": { + "type": "object", + "properties": { + "id": { + "type": "string", + "example": "1" + }, + "label": { + "type": "string", + "example": "人工智能" + }, + "type": { + "type": "string", + "example": "概念" + } + } + }, "models.UpdateNodeRequest": { "type": "object", "properties": { diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index 5a8e458..3a2fd90 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -196,6 +196,44 @@ definitions: $ref: '#/definitions/models.Node' type: array type: object + models.SimpleEdge: + properties: + label: + example: 包含 + type: string + source: + example: "1" + type: string + target: + example: "2" + type: string + type: + example: CONTAINS + type: string + type: object + models.SimpleGraphData: + properties: + edges: + items: + $ref: '#/definitions/models.SimpleEdge' + type: array + nodes: + items: + $ref: '#/definitions/models.SimpleNode' + type: array + type: object + models.SimpleNode: + properties: + id: + example: "1" + type: string + label: + example: 人工智能 + type: string + type: + example: 概念 + type: string + type: object models.UpdateNodeRequest: properties: label: @@ -302,6 +340,21 @@ paths: schema: $ref: '#/definitions/models.ErrorResponse' summary: 获取图数据 + /api/graph/simpleJson: + get: + description: 获取知识图谱的全部节点和边数据(仅保留核心信息,适合LLM处理) + produces: + - application/json + responses: + "200": + description: 成功 + schema: + $ref: '#/definitions/models.SimpleGraphData' + "500": + description: 内部错误 + schema: + $ref: '#/definitions/models.ErrorResponse' + summary: 获取简化图数据 /api/graph/stats: get: description: 获取知识图谱的节点数、边数等统计信息 diff --git a/backend/handlers/graph_handler.go b/backend/handlers/graph_handler.go index c33ca86..cb77e2f 100644 --- a/backend/handlers/graph_handler.go +++ b/backend/handlers/graph_handler.go @@ -38,3 +38,14 @@ func (h *GraphHandler) GetStats(c *gin.Context) { stats := h.service.GetStats() c.JSON(http.StatusOK, stats) } + +// @Summary 获取简化图数据 +// @Description 获取知识图谱的全部节点和边数据(仅保留核心信息,适合LLM处理) +// @Produce json +// @Success 200 {object} models.SimpleGraphData "成功" +// @Failure 500 {object} models.ErrorResponse "内部错误" +// @Router /api/graph/simpleJson [get] +func (h *GraphHandler) GetSimpleGraphData(c *gin.Context) { + data := h.service.GetSimpleGraphData() + c.JSON(http.StatusOK, data) +} diff --git a/backend/main.go b/backend/main.go index c85e1c9..d6ebf7d 100644 --- a/backend/main.go +++ b/backend/main.go @@ -65,6 +65,7 @@ func main() { { api.GET("/graph", graphHandler.GetGraphData) api.GET("/graph/stats", graphHandler.GetStats) + api.GET("/graph/simpleJson", graphHandler.GetSimpleGraphData) api.GET("/search", searchHandler.SearchNodes) @@ -88,6 +89,7 @@ func main() { log.Println(" GET /health - Health check") log.Println(" GET /api/graph - Get all graph data") log.Println(" GET /api/graph/stats - Get graph statistics") + log.Println(" GET /api/graph/simpleJson - Get simplified graph data (for LLM)") log.Println(" GET /api/search?q=query - Search nodes") log.Println(" GET /api/nodes/:id - Get node by ID") log.Println(" GET /api/nodes/:id/neighbors - Get node neighbors") diff --git a/backend/models/graph.go b/backend/models/graph.go index eeb6352..1823116 100644 --- a/backend/models/graph.go +++ b/backend/models/graph.go @@ -24,3 +24,24 @@ type GraphData struct { Nodes []Node `json:"nodes"` Edges []Edge `json:"edges"` } + +// SimpleNode 简化版节点结构,仅保留核心信息,适合 LLM 处理 +type SimpleNode struct { + ID string `json:"id" example:"1"` + Label string `json:"label" example:"人工智能"` + Type string `json:"type,omitempty" example:"概念"` +} + +// SimpleEdge 简化版边结构,仅保留核心信息,适合 LLM 处理 +type SimpleEdge struct { + Source string `json:"source" example:"1"` + Target string `json:"target" example:"2"` + Type string `json:"type,omitempty" example:"CONTAINS"` + Label string `json:"label,omitempty" example:"包含"` +} + +// SimpleGraphData 简化版图数据,适合 LLM 处理 +type SimpleGraphData struct { + Nodes []SimpleNode `json:"nodes"` + Edges []SimpleEdge `json:"edges"` +} diff --git a/backend/services/neo4j_service.go b/backend/services/neo4j_service.go index 8e3f698..a88cc1d 100644 --- a/backend/services/neo4j_service.go +++ b/backend/services/neo4j_service.go @@ -215,6 +215,69 @@ func (s *Neo4jService) GetStats() map[string]int { } } +// GetSimpleGraphData 获取简化的图数据,仅保留核心信息,适合 LLM 处理 +func (s *Neo4jService) GetSimpleGraphData() models.SimpleGraphData { + ctx := context.Background() + var nodes []models.SimpleNode + var edges []models.SimpleEdge + + 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 models.SimpleGraphData{} + } + for _, record := range nodeResult.Records { + if v, ok := record.Get("n"); ok { + if n, ok := v.(neo4j.Node); ok { + props := n.Props + node := models.SimpleNode{ + ID: getStr(props, "id"), + Label: getStr(props, "label"), + Type: getStr(props, "type"), + } + nodes = append(nodes, node) + } + } + } + + 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 models.SimpleGraphData{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 { + props := rel.Props + edge := models.SimpleEdge{ + Source: getStr(props, "source"), + Target: getStr(props, "target"), + Type: rel.Type, + Label: getStr(props, "label"), + } + if s, ok := source.(string); ok { + edge.Source = s + } + if t, ok := target.(string); ok { + edge.Target = t + } + edges = append(edges, edge) + } + } + + return models.SimpleGraphData{Nodes: nodes, Edges: edges} +} + func neo4jNodeToModel(n neo4j.Node) models.Node { props := n.Props node := models.Node{ diff --git a/backend/services/service.go b/backend/services/service.go index 23644b5..91f2986 100644 --- a/backend/services/service.go +++ b/backend/services/service.go @@ -4,6 +4,7 @@ import "knowledge-graph-backend/models" type GraphService interface { GetGraphData() models.GraphData + GetSimpleGraphData() models.SimpleGraphData GetNodeByID(id string) (models.Node, bool) SearchNodes(query string) []models.Node GetNeighbors(nodeID string) (models.NeighborResponse, bool)