fix: E1 extractPotentialEntities 使用 utf8.RuneCountInString 而非 len() 计算中文字符数
- len(string) 返回字节数而非字符数,导致所有 2-8 字中文词被错误过滤 - 原始代码用 continue,现已恢复正确迭代逻辑 - 添加 unicode/utf8 导入
This commit is contained in:
parent
31712986de
commit
69d41c3087
|
|
@ -20,6 +20,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
|
||||
"github.com/xiaoxue/memoryweave/internal/models"
|
||||
|
|
@ -441,11 +442,30 @@ type PathResult struct {
|
|||
Score float64
|
||||
}
|
||||
|
||||
// deriveNamespaceForGraph 将 namespace 转为图谱中的实际格式
|
||||
// hermes → hermes-main, shared → shared, default → default
|
||||
func deriveNamespaceForGraph(ns string) string {
|
||||
if ns == "" {
|
||||
return ""
|
||||
}
|
||||
// already full form
|
||||
if strings.HasSuffix(ns, "-main") || ns == "shared" || ns == "default" {
|
||||
return ns
|
||||
}
|
||||
// bare name → full form (hermes → hermes-main)
|
||||
return ns + "-main"
|
||||
}
|
||||
|
||||
func buildNamespaceClause(namespace string) string {
|
||||
if namespace == "" {
|
||||
return "1=1"
|
||||
}
|
||||
return fmt.Sprintf("(e.namespace = '%s' OR e.namespace = 'default')", escape(namespace))
|
||||
// 确保用图谱中的实际格式
|
||||
derived := deriveNamespaceForGraph(namespace)
|
||||
if derived == "shared" {
|
||||
return "(e.namespace = 'shared')"
|
||||
}
|
||||
return fmt.Sprintf("(e.namespace = '%s' OR e.namespace = 'default')", escape(derived))
|
||||
}
|
||||
|
||||
// sortResultsByScore 简单选择排序
|
||||
|
|
@ -567,30 +587,32 @@ func (gs *SQLiteGraphStore) ExpandFromResults(results []models.RecallResult, nam
|
|||
}
|
||||
seen[r.ID] = true
|
||||
|
||||
// 从内容中提取可能作为实体的关键词
|
||||
fmt.Printf("[E1] content=%q\n", r.Content)
|
||||
entities := extractPotentialEntities(r.Content)
|
||||
fmt.Printf("[E1] entities=%v, namespace=%q\n", entities, namespace)
|
||||
for _, entity := range entities {
|
||||
fmt.Printf("[E1] trying entity=%q\n", entity)
|
||||
if seenEntities[entity] {
|
||||
continue
|
||||
}
|
||||
seenEntities[entity] = true
|
||||
|
||||
// SQLite 图谱节点 ID 格式: n_{entity_name},需 normalizeEntityID 转换
|
||||
nodeID := normalizeEntityID(entity)
|
||||
fmt.Printf("[E1] Navigate(nodeID=%q, ns=%q)\n", nodeID, namespace)
|
||||
paths, _ := gs.Navigate(nodeID, maxHops, namespace)
|
||||
fmt.Printf("[E1] Navigate returned %d paths for entity=%q\n", len(paths), entity)
|
||||
for _, p := range paths {
|
||||
// Navigate 返回的是单条边 (source/target/relation/weight)
|
||||
// 有两种情况:
|
||||
// 1. source == entity(正向边):target 是下游邻居
|
||||
// 2. target == entity(反向边):source 是上游邻居
|
||||
// Navigate 返回字段: from, to, relation, weight, hop
|
||||
var neighbor, rel string
|
||||
src, _ := p["source"].(string)
|
||||
tgt, _ := p["target"].(string)
|
||||
from, _ := p["from"].(string)
|
||||
to, _ := p["to"].(string)
|
||||
relVal, _ := p["relation"].(string)
|
||||
if src == entity && tgt != "" {
|
||||
neighbor = tgt
|
||||
if from == entity && to != "" {
|
||||
neighbor = to
|
||||
rel = relVal
|
||||
} else if tgt == entity && src != "" {
|
||||
neighbor = src
|
||||
} else if to == entity && from != "" {
|
||||
neighbor = from
|
||||
rel = "↩ " + relVal
|
||||
}
|
||||
if neighbor == "" {
|
||||
|
|
@ -625,8 +647,8 @@ func extractPotentialEntities(text string) []string {
|
|||
i++
|
||||
}
|
||||
chinese := string(runes[start:i])
|
||||
// 不等式:2 <= len(chinese) <= 8
|
||||
if len(chinese) >= 2 && len(chinese) <= 8 && !seen[chinese] {
|
||||
// 不等式:2 <= len(chinese) <= 8(字符数,非字节数)
|
||||
if utf8.RuneCountInString(chinese) >= 2 && utf8.RuneCountInString(chinese) <= 8 && !seen[chinese] {
|
||||
seen[chinese] = true
|
||||
entities = append(entities, chinese)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue