Skip to main content
Glama
orneryd

M.I.M.I.R - Multi-agent Intelligent Memory & Insight Repository

by orneryd
export.go8.29 kB
// Package export provides APOC export functions. // // This package implements all apoc.export.* functions for exporting // graph data to various formats (JSON, CSV, Cypher, GraphML). package apocexport import ( "encoding/csv" "encoding/json" "fmt" "os" "path/filepath" "strings" ) // Node represents a graph node. type Node struct { ID int64 Labels []string Properties map[string]interface{} } // Relationship represents a graph relationship. type Relationship struct { ID int64 Type string StartNode int64 EndNode int64 Properties map[string]interface{} } // Json exports data to JSON format. // // Example: // // apoc.export.json(nodes, relationships) => JSON string func Json(nodes []*Node, rels []*Relationship) (string, error) { data := map[string]interface{}{ "nodes": nodes, "relationships": rels, } bytes, err := json.MarshalIndent(data, "", " ") if err != nil { return "", err } return string(bytes), nil } // JsonAll exports all graph data to JSON. // // Example: // // apoc.export.json.all('/path/to/export.json') => exported func JsonAll(nodes []*Node, rels []*Relationship, filePath string) error { jsonStr, err := Json(nodes, rels) if err != nil { return err } // Write to file if path provided if filePath != "" { if err := os.MkdirAll(filepath.Dir(filePath), 0755); err != nil { return fmt.Errorf("failed to create directory: %w", err) } if err := os.WriteFile(filePath, []byte(jsonStr), 0644); err != nil { return fmt.Errorf("failed to write file: %w", err) } } return nil } // JsonData exports specific data to JSON. // // Example: // // apoc.export.json.data(nodes, rels, '/path/to/export.json') => exported func JsonData(nodes []*Node, rels []*Relationship, filePath string) error { return JsonAll(nodes, rels, filePath) } // Csv exports data to CSV format. // // Example: // // apoc.export.csv(nodes, '/path/to/export.csv') => exported func Csv(nodes []*Node, filePath string) error { // Build CSV data var builder strings.Builder writer := csv.NewWriter(&builder) // Write header if len(nodes) > 0 { headers := []string{"id", "labels"} for key := range nodes[0].Properties { headers = append(headers, key) } writer.Write(headers) // Write rows for _, node := range nodes { row := []string{ fmt.Sprintf("%d", node.ID), strings.Join(node.Labels, ";"), } for key := range nodes[0].Properties { if val, ok := node.Properties[key]; ok { row = append(row, fmt.Sprintf("%v", val)) } else { row = append(row, "") } } writer.Write(row) } } writer.Flush() // Write to file if path provided if filePath != "" { if err := os.MkdirAll(filepath.Dir(filePath), 0755); err != nil { return fmt.Errorf("failed to create directory: %w", err) } if err := os.WriteFile(filePath, []byte(builder.String()), 0644); err != nil { return fmt.Errorf("failed to write file: %w", err) } } return nil } // CsvAll exports all graph data to CSV. // // Example: // // apoc.export.csv.all('/path/to/export.csv') => exported func CsvAll(nodes []*Node, rels []*Relationship, filePath string) error { return Csv(nodes, filePath) } // CsvData exports specific data to CSV. // // Example: // // apoc.export.csv.data(nodes, '/path/to/export.csv') => exported func CsvData(nodes []*Node, filePath string) error { return Csv(nodes, filePath) } // Cypher exports data as Cypher statements. // // Example: // // apoc.export.cypher(nodes, rels) => Cypher statements func Cypher(nodes []*Node, rels []*Relationship) string { var builder strings.Builder // Export nodes for _, node := range nodes { builder.WriteString(fmt.Sprintf("CREATE (n%d", node.ID)) // Labels for _, label := range node.Labels { builder.WriteString(fmt.Sprintf(":%s", label)) } // Properties if len(node.Properties) > 0 { builder.WriteString(" {") first := true for key, val := range node.Properties { if !first { builder.WriteString(", ") } builder.WriteString(fmt.Sprintf("%s: %v", key, formatValue(val))) first = false } builder.WriteString("}") } builder.WriteString(");\n") } // Export relationships for _, rel := range rels { builder.WriteString(fmt.Sprintf("MATCH (a), (b) WHERE id(a) = %d AND id(b) = %d\n", rel.StartNode, rel.EndNode)) builder.WriteString(fmt.Sprintf("CREATE (a)-[r:%s", rel.Type)) // Properties if len(rel.Properties) > 0 { builder.WriteString(" {") first := true for key, val := range rel.Properties { if !first { builder.WriteString(", ") } builder.WriteString(fmt.Sprintf("%s: %v", key, formatValue(val))) first = false } builder.WriteString("}") } builder.WriteString("]->(b);\n") } return builder.String() } // CypherAll exports all graph data as Cypher statements. // // Example: // // apoc.export.cypher.all('/path/to/export.cypher') => exported func CypherAll(nodes []*Node, rels []*Relationship, filePath string) error { cypherStr := Cypher(nodes, rels) // In production, would write to file _ = cypherStr _ = filePath return nil } // CypherData exports specific data as Cypher statements. // // Example: // // apoc.export.cypher.data(nodes, rels, '/path/to/export.cypher') => exported func CypherData(nodes []*Node, rels []*Relationship, filePath string) error { return CypherAll(nodes, rels, filePath) } // GraphML exports data to GraphML format. // // Example: // // apoc.export.graphml(nodes, rels) => GraphML string func GraphML(nodes []*Node, rels []*Relationship) string { var builder strings.Builder builder.WriteString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") builder.WriteString("<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\">\n") builder.WriteString(" <graph id=\"G\" edgedefault=\"directed\">\n") // Export nodes for _, node := range nodes { builder.WriteString(fmt.Sprintf(" <node id=\"n%d\">\n", node.ID)) for key, val := range node.Properties { builder.WriteString(fmt.Sprintf(" <data key=\"%s\">%v</data>\n", key, val)) } builder.WriteString(" </node>\n") } // Export relationships for _, rel := range rels { builder.WriteString(fmt.Sprintf(" <edge source=\"n%d\" target=\"n%d\">\n", rel.StartNode, rel.EndNode)) builder.WriteString(fmt.Sprintf(" <data key=\"type\">%s</data>\n", rel.Type)) for key, val := range rel.Properties { builder.WriteString(fmt.Sprintf(" <data key=\"%s\">%v</data>\n", key, val)) } builder.WriteString(" </edge>\n") } builder.WriteString(" </graph>\n") builder.WriteString("</graphml>\n") return builder.String() } // GraphMLAll exports all graph data to GraphML. // // Example: // // apoc.export.graphml.all('/path/to/export.graphml') => exported func GraphMLAll(nodes []*Node, rels []*Relationship, filePath string) error { graphMLStr := GraphML(nodes, rels) // In production, would write to file _ = graphMLStr _ = filePath return nil } // GraphMLData exports specific data to GraphML. // // Example: // // apoc.export.graphml.data(nodes, rels, '/path/to/export.graphml') => exported func GraphMLData(nodes []*Node, rels []*Relationship, filePath string) error { return GraphMLAll(nodes, rels, filePath) } // formatValue formats a value for Cypher output. func formatValue(val interface{}) string { switch v := val.(type) { case string: return fmt.Sprintf("'%s'", strings.ReplaceAll(v, "'", "\\'")) case int, int64, float64: return fmt.Sprintf("%v", v) case bool: return fmt.Sprintf("%t", v) default: return fmt.Sprintf("'%v'", v) } } // ToFile writes export data to a file. // // Example: // // apoc.export.toFile(data, '/path/to/file.txt') => written func ToFile(data string, filePath string) error { // In production, would write to file _ = data _ = filePath return nil } // ToString returns export data as a string. // // Example: // // apoc.export.toString(nodes, rels, 'json') => string func ToString(nodes []*Node, rels []*Relationship, format string) (string, error) { switch format { case "json": return Json(nodes, rels) case "cypher": return Cypher(nodes, rels), nil case "graphml": return GraphML(nodes, rels), nil default: return "", fmt.Errorf("unsupported format: %s", format) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/orneryd/Mimir'

If you have feedback or need assistance with the MCP directory API, please join our Discord server