Skip to content

Cypher and openCypher

Gabor Szarnyas edited this page Apr 3, 2021 · 8 revisions

To flip the direction of an edge in Cypher, do a regex search and replace.

Search string:

(\(.*?\))<-(\[.*?:.*?\])-(\(.*?\))

Replace string:

$3-$2->$1

Export

https://neo4j-contrib.github.io/neo4j-apoc-procedures/#_export_to_csv

Generate export command for nodes

MATCH (n)
WITH n, labels(n) AS labels, keys(n) AS propertyKeys
UNWIND labels AS label
UNWIND propertyKeys AS propertyKey
WITH DISTINCT
  label,
  'n.' + propertyKey + ' AS `' + propertyKey + ':' +
    CASE n[propertyKey] = true OR n[propertyKey] = false WHEN true THEN 'BOOLEAN' ELSE
    CASE toInteger(n[propertyKey]) = n[propertyKey]      WHEN true THEN 'INT'     ELSE
    CASE toFloat(n[propertyKey]) = n[propertyKey]        WHEN true THEN 'FLOAT'   ELSE
    'STRING' END END END + '`'
    AS exportKey
WITH
  label, REDUCE(acc = '', k IN collect(exportKey) | acc + ', ' + k) AS property
WITH label, COLLECT(property) AS properties
WITH label + '.csv' AS filename,
  'MATCH (n:' + label + ') ' +
  REDUCE(
    acc = 'RETURN ID(n) AS `:ID`',
    property IN properties
    | acc + property
  ) AS query
ORDER BY label
WITH query, filename
CALL apoc.export.csv.query(query, filename, {})
YIELD file
RETURN file

Generate export command for relationships

Note: properties are not handled, but the approach used for nodes should work here as well.

MATCH (v)
OPTIONAL MATCH (v)-[r]-(w)
WITH DISTINCT type(r) AS type
RETURN
  'MATCH (n)-[:' + type + ']->(m) ' +
  'RETURN ID(n) AS `:START_ID`, ID(m) AS `:END_ID`' AS query
ORDER BY type
CALL apoc.export.csv.query(query, filename, {})
YIELD file
RETURN file

A python script for extracting data in CSV format

  • The script assumes each value has an Id attribute.
  • The script won't export edge properties.
#!/usr/bin/env python3

import itertools
from neo4j.v1 import GraphDatabase, basic_auth

driver = GraphDatabase.driver("bolt://localhost:7687", auth=basic_auth("neo4j", "147258192168"))
session = driver.session()

def exportRelation(etype):
    print("Exporting type %s" % etype)
    attributeList = ":START_ID,:END_ID"
    
    with open("%s.csv" % etype, 'w') as f:
        valueResult = session.run("MATCH (a)-[:%s]->(b) RETURN a.Id,b.Id" % (etype))
        for record in valueResult:
            f.write("%s,%s\n" % (record['a.Id'], record['b.Id']))

def exportLabel(label):
    print("Exporting label %s" % label)
    properties = []
    propertyResult = session.run("MATCH (n:%s) UNWIND keys(n) AS key RETURN DISTINCT key" % label)
    for record in propertyResult:
        properties.append(record["key"])

    with open("%s.csv" % label, 'w') as f:
        for p in properties:
            f.write('"%s",' % p)
        f.write('\n')

        attributeList = ""
        for p in properties:
            attributeList = "%sn.%s," % (attributeList, p)

        valueResult = session.run("MATCH (n:%s) RETURN %s" % (label, attributeList[:-1]))
        for record in valueResult:
            for p in properties:
                val = record["n.%s" % p]
                if type(val) is int or type(val) is float:
                    f.write('%s,' % val)
                else:
                    f.write('"%s",' % val)
            f.write('\n')

for record in session.run("MATCH (n) UNWIND labels(n) AS label RETURN DISTINCT label"):
    exportLabel(record["label"])


for record in session.run("MATCH ()-[e]->() RETURN DISTINCT type(e) AS type"):
    exportRelation(record["type"])
    
session.close()
Clone this wiki locally