
Using neo2R with Local Neo4j Instances
August 23 2026
Source:vignettes/neo2R-local.Rmd
neo2R-local.RmdIntroduction
This vignette demonstrates how to connect to a local Neo4j instance and import data from data frames.
Connecting to Local Neo4j
After installing Neo4j, use
startGraph() to initialize the connection from R. If
authentication has been disabled in Neo4j by setting
NEO4J_AUTH=none, neither username nor password are
required.
If you’re connecting to a local instance of Neo4j and an import directory has been defined in the configuration, you can specify it in order to allow import from data frames.
library(neo2R)
graph <- startGraph(
"https://localhost:7473",
username = "neo4j",
password = "donttrustusers",
importPath = "~/neo4j_home/neo4jImport",
.opts = list(ssl_verifypeer = 0)
)Importing Data from Data Frames
If you’re connected to a local instance of Neo4j and an import
directory has been defined (see above), you can import data from data
frames. Use the row prefix to refer to the data frame
column.
# Create an index to speed-up MERGE
if (as.integer(graph$version[[1]]) >= 5) {
try(cypher(graph, 'CREATE INDEX FOR (n:TestNode) ON (n.name)'), silent = TRUE)
} else {
try(cypher(graph, 'CREATE INDEX ON :TestNode(name)'), silent = TRUE)
}
#> Neo.ClientError.Schema.EquivalentSchemaRuleAlreadyExists
#> An equivalent index already exists, 'Index( id=3, name='index_e8759119', type='RANGE', schema=(:TestNode {name}), indexProvider='range-1.0' )'.
# Define node properties in a data frame
set.seed(1)
nn <- 100000
nodes <- data.frame(
"name" = paste(
sample(LETTERS, nn, replace = TRUE),
sample.int(nn, nn, replace = FALSE)
),
"value" = rnorm(nn, 10, 3),
stringsAsFactors = FALSE
)
# Import nodes
import_from_df(
graph = graph,
cql = 'MERGE (n:TestNode {name: row.name, value: toFloat(row.value)})',
toImport = nodes
)
# Define edge properties in a data frame
ne <- 100000
edges <- data.frame(
"from" = sample(nodes$name, ne, replace = TRUE),
"to" = sample(nodes$name, ne, replace = TRUE),
"property" = round(runif(ne) * 10),
stringsAsFactors = FALSE
)
# Import edges
import_from_df(
graph = graph,
cql = prepCql(
'MATCH (f:TestNode {name: row.from})',
'MATCH (t:TestNode {name: row.to})',
'MERGE (f)-[r:TestEdge {property: toInteger(row.property)}]->(t)'
),
toImport = edges
)Querying the Neo4j Database
You can query the Neo4j graph database using the
cypher() function. Depending on the query, the function can
return data in a data frame (by setting result = "row") or
in a list with nodes, relationships and paths returned by the query by
setting result = "graph".
# Get TestNode with value smaller than 4
# According to the normal distribution we expect 2.5% of the total
# number of nodes ==> ~2500 nodes
df <- cypher(
graph,
prepCql(
'MATCH (n:TestNode) WHERE n.value <= 4',
'RETURN n.name as name, n.value as value'
)
)
print(dim(df))
#> [1] 2253 2
print(head(df))
#> name value
#> 1 N 2585 1.965486
#> 2 L 72527 3.345461
#> 3 Y 54240 2.372623
#> 4 N 1436 1.500713
#> 5 T 21434 3.592195
#> 6 M 91787 2.504475
# Multiple queries can be sent at once
dfl <- multicypher(
graph,
sprintf(
paste(
'MATCH (n:TestNode) WHERE n.value <= %s',
'RETURN n.name as name, n.value as value'
),
2:4
)
)
print(lapply(dfl, dim))
#> [[1]]
#> [1] 386 2
#>
#> [[2]]
#> [1] 954 2
#>
#> [[3]]
#> [1] 2253 2
# Get all paths of length 5 starting from a subset of nodes
net <- cypher(
graph,
prepCql(
'MATCH p=(f:TestNode)-[:TestEdge*5..5]->(t:TestNode) WHERE f.value < 3',
'RETURN p'
),
result = "graph"
)
print(lapply(net, head, 3))
#> $nodes
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7`
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7`$elementId
#> [1] "4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7"
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7`$labels
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7`$labels[[1]]
#> [1] "TestNode"
#>
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7`$properties
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7`$properties$name
#> [1] "N 2585"
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7`$properties$value
#> [1] 1.965486
#>
#>
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:97347`
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:97347`$elementId
#> [1] "4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:97347"
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:97347`$labels
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:97347`$labels[[1]]
#> [1] "TestNode"
#>
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:97347`$properties
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:97347`$properties$name
#> [1] "V 30913"
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:97347`$properties$value
#> [1] 10.389
#>
#>
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:13440`
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:13440`$elementId
#> [1] "4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:13440"
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:13440`$labels
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:13440`$labels[[1]]
#> [1] "TestNode"
#>
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:13440`$properties
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:13440`$properties$name
#> [1] "Z 33864"
#>
#> $nodes$`4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:13440`$properties$value
#> [1] 5.65467
#>
#>
#>
#>
#> $relationships
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543`
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543`$elementId
#> [1] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543`$startNodeElementId
#> [1] "4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543`$endNodeElementId
#> [1] "4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:97347"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543`$type
#> [1] "TestEdge"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543`$properties
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543`$properties$property
#> [1] 8
#>
#>
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423`
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423`$elementId
#> [1] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423`$startNodeElementId
#> [1] "4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:97347"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423`$endNodeElementId
#> [1] "4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:13440"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423`$type
#> [1] "TestEdge"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423`$properties
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423`$properties$property
#> [1] 0
#>
#>
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:470`
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:470`$elementId
#> [1] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:470"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:470`$startNodeElementId
#> [1] "4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:13440"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:470`$endNodeElementId
#> [1] "4:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:79444"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:470`$type
#> [1] "TestEdge"
#>
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:470`$properties
#> $relationships$`5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:470`$properties$property
#> [1] 10
#>
#>
#>
#>
#> $paths
#> $paths[[1]]
#> [1] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543"
#> [2] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423"
#> [3] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:470"
#> [4] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7553"
#> [5] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:94678"
#>
#> $paths[[2]]
#> [1] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543"
#> [2] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423"
#> [3] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:470"
#> [4] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:7553"
#> [5] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:98608"
#>
#> $paths[[3]]
#> [1] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:93543"
#> [2] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:31423"
#> [3] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:69425"
#> [4] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:71263"
#> [5] "5:189c469e-6afa-4d4f-b15c-f46d0ff5d9b4:58428"
print(table(unlist(lapply(net$paths, length))))
#>
#> 5
#> 945Further Reading
- Neo4j Cypher reference — query language docs