From 7bcbed8c3547e55287972bd0bccc7c9e9d8ec495 Mon Sep 17 00:00:00 2001
From: ai_xiaopei <xiaopei@aisim.cn>
Date: Fri, 21 Aug 2026 19:14:11 +0800
Subject: [PATCH] feat(index): nodes 表增加 node_type 列,查询过滤虚拟节点

---
 internal/graph/builder.go |   24 ++++++++++++++++++++----
 1 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/internal/graph/builder.go b/internal/graph/builder.go
index 9b5ca4e..ce5f0ea 100644
--- a/internal/graph/builder.go
+++ b/internal/graph/builder.go
@@ -1,6 +1,9 @@
 package graph
 
 import (
+	"path/filepath"
+	"strings"
+
 	"github.com/aisim/kb-cli/internal/vault"
 )
 
@@ -12,13 +15,19 @@
 	labelToID := make(map[string]int64)
 	nextVirtualID := int64(1000000) // 虚拟节点从 1000000 开始
 
-	getOrCreateVirtualNode := func(label string) int64 {
+	getOrCreateVirtualNode := func(label, nodeType string) int64 {
 		if id, ok := labelToID[label]; ok {
 			return id
 		}
 		id := nextVirtualID
 		nextVirtualID++
 		labelToID[label] = id
+		g.Nodes = append(g.Nodes, &Node{
+			ID:       id,
+			Path:     label, // label 已含 "tag:"/"entity:" 前缀
+			Title:    strings.TrimPrefix(strings.TrimPrefix(label, "tag:"), "entity:"),
+			NodeType: nodeType,
+		})
 		return id
 	}
 
@@ -28,6 +37,7 @@
 			Path:      f.Path,
 			Title:     f.Title,
 			Section:   f.Section,
+			NodeType:  "file",
 			Tags:      f.Tags,
 			Entities:  f.Entities,
 			Wikilinks: f.Wikilinks,
@@ -37,7 +47,7 @@
 
 		// 创建 tag 边
 		for _, tag := range f.Tags {
-			virtualID := getOrCreateVirtualNode("tag:" + tag)
+			virtualID := getOrCreateVirtualNode("tag:"+tag, "tag")
 			g.Edges = append(g.Edges, &Edge{
 				FromNode: node.ID,
 				ToNode:   virtualID,
@@ -48,7 +58,7 @@
 
 		// 创建 entity 边
 		for _, entity := range f.Entities {
-			virtualID := getOrCreateVirtualNode("entity:" + entity)
+			virtualID := getOrCreateVirtualNode("entity:"+entity, "entity")
 			g.Edges = append(g.Edges, &Edge{
 				FromNode: node.ID,
 				ToNode:   virtualID,
@@ -92,5 +102,11 @@
 	}
 	// 匹配文件名(不含扩展名和编号前缀)
 	// 例如:[[充装规格配置]] 匹配 "知识/002-充装规格配置.md"
-	return false // 简化版,后续可扩展
+	base := filepath.Base(node.Path)
+	base = strings.TrimSuffix(base, ".md")
+	// 去掉编号前缀(如 "002-")
+	if idx := strings.Index(base, "-"); idx >= 0 {
+		base = base[idx+1:]
+	}
+	return base == link || node.Title == link
 }

--
Gitblit v1.10.0