package knowledge import ( "strings" "unicode/utf8" ) const maxDerivedTagRunes = 8 func DeriveSearchTagsFromGraph(graph *Graph) { if graph == nil { return } for i := range graph.Nodes { graph.Nodes[i].DerivedTags = deriveNodeTags(graph.Nodes[i]) } graph.PainTagCount = CountPainTagCandidates(graph.Nodes) } func deriveNodeTags(node Node) DerivedTags { label := strings.TrimSpace(node.Label) if label == "" { return DerivedTags{} } relevance := []string{clampTag(label)} recency := []string{} if IsPainNode(node) { if q := BuildRecencyQuery(label); q != "" { recency = append(recency, clampTag(q)) } if node.Layer >= 1 { recency = append(recency, clampTag(label+" 推薦")) } } relevance = uniqueTags(relevance) recency = uniqueTags(recency) return DerivedTags{Relevance: relevance, Recency: recency} } func clampTag(text string) string { text = strings.TrimSpace(text) if text == "" { return "" } if utf8.RuneCountInString(text) <= maxDerivedTagRunes { return text } runes := []rune(text) return string(runes[:maxDerivedTagRunes]) } func uniqueTags(items []string) []string { seen := map[string]struct{}{} out := make([]string, 0, len(items)) for _, item := range items { item = strings.TrimSpace(item) if item == "" { continue } if _, ok := seen[item]; ok { continue } seen[item] = struct{}{} out = append(out, item) } return out }