refactor: 重构neo4j服务
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||
|
||||
"knowledge-graph-backend/internal/model"
|
||||
)
|
||||
|
||||
func neo4jNodeToModel(n neo4j.Node) model.Node {
|
||||
props := n.Props
|
||||
node := model.Node{
|
||||
ID: getStr(props, "id"),
|
||||
Label: getStr(props, "label"),
|
||||
Type: getStr(props, "type"),
|
||||
Properties: make(map[string]interface{}),
|
||||
}
|
||||
if v, ok := props["x"]; ok && v != nil {
|
||||
node.X = getFloat64(v)
|
||||
}
|
||||
if v, ok := props["y"]; ok && v != nil {
|
||||
node.Y = getFloat64(v)
|
||||
}
|
||||
if v, ok := props["style"]; ok && v != nil {
|
||||
if s, ok := v.(map[string]interface{}); ok {
|
||||
node.Style = s
|
||||
}
|
||||
}
|
||||
for k, v := range props {
|
||||
switch k {
|
||||
case "id", "label", "type", "x", "y", "style":
|
||||
default:
|
||||
node.Properties[k] = v
|
||||
}
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func neo4jRelToModel(r neo4j.Relationship) model.Edge {
|
||||
props := r.Props
|
||||
edge := model.Edge{
|
||||
ID: getStr(props, "id"),
|
||||
Label: getStr(props, "label"),
|
||||
Type: r.Type,
|
||||
Properties: make(map[string]interface{}),
|
||||
}
|
||||
if v, ok := props["style"]; ok && v != nil {
|
||||
if s, ok := v.(map[string]interface{}); ok {
|
||||
edge.Style = s
|
||||
}
|
||||
}
|
||||
for k, v := range props {
|
||||
switch k {
|
||||
case "id", "label", "style":
|
||||
default:
|
||||
edge.Properties[k] = v
|
||||
}
|
||||
}
|
||||
return edge
|
||||
}
|
||||
|
||||
func getStr(props map[string]any, key string) string {
|
||||
if v, ok := props[key]; ok && v != nil {
|
||||
if s, ok := v.(string); ok {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getFloat64(v any) float64 {
|
||||
switch val := v.(type) {
|
||||
case float64:
|
||||
return val
|
||||
case int64:
|
||||
return float64(val)
|
||||
case int:
|
||||
return float64(val)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func getInt(record *neo4j.Record, key string) int {
|
||||
v, _ := record.Get(key)
|
||||
switch val := v.(type) {
|
||||
case int64:
|
||||
return int(val)
|
||||
case int:
|
||||
return val
|
||||
case float64:
|
||||
return int(val)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func buildNodeProps(req model.CreateNodeRequest) map[string]any {
|
||||
props := map[string]any{"id": req.ID, "label": req.Label}
|
||||
if req.Type != "" {
|
||||
props["type"] = req.Type
|
||||
}
|
||||
if req.X != 0 {
|
||||
props["x"] = req.X
|
||||
}
|
||||
if req.Y != 0 {
|
||||
props["y"] = req.Y
|
||||
}
|
||||
for k, v := range req.Properties {
|
||||
if isReservedNodeProperty(k) {
|
||||
continue
|
||||
}
|
||||
props[k] = v
|
||||
}
|
||||
return props
|
||||
}
|
||||
|
||||
func buildEdgeProps(req model.CreateEdgeRequest) map[string]any {
|
||||
props := map[string]any{"id": req.ID, "label": req.Label}
|
||||
for k, v := range req.Properties {
|
||||
if isReservedEdgeProperty(k) {
|
||||
continue
|
||||
}
|
||||
props[k] = v
|
||||
}
|
||||
return props
|
||||
}
|
||||
|
||||
func isReservedNodeProperty(key string) bool {
|
||||
switch key {
|
||||
case "id", "label", "type", "x", "y", "style":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isReservedEdgeProperty(key string) bool {
|
||||
switch key {
|
||||
case "id", "label", "type", "style", "source", "target":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func sanitizeLabel(label string) string {
|
||||
if label == "" {
|
||||
return ""
|
||||
}
|
||||
var b strings.Builder
|
||||
for i, r := range label {
|
||||
if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '_' {
|
||||
b.WriteRune(r)
|
||||
continue
|
||||
}
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
b.WriteRune('_')
|
||||
}
|
||||
return strings.Trim(b.String(), "_")
|
||||
}
|
||||
|
||||
func sanitizeRelationshipType(relType string) string {
|
||||
if relType == "" {
|
||||
return ""
|
||||
}
|
||||
return sanitizeLabel(strings.ToUpper(relType))
|
||||
}
|
||||
|
||||
func wrapNotFound(entity string, id string) error {
|
||||
return fmt.Errorf("%s with id %s not found", entity, id)
|
||||
}
|
||||
Reference in New Issue
Block a user