README
The aim of neo2R is to provide simple and low-level connectors for querying Neo4j graph databases. The objects returned by the query functions are either lists or data frames with minimal post-processing, allowing fast handling of queries returning many records and letting the user apply post-processing according to their data model and needs. It has been developed to support the BED package (F1000Research). Other packages such as RNeo4j or neo4R provide connectors to Neo4j databases with additional features.
Installation
From CRAN
install.packages("neo2R")Dependencies
The following R packages available on CRAN are required:
- jsonlite: A Simple and Robust JSON Parser and Generator for R
- httr2: Perform HTTP Requests and Process the Responses
- utils: The R Utils Package
Installation from github
devtools::install_github("patzaw/neo2R")
Use
Connect to Neo4j Aura
Neo4j Aura is
Neo4j’s fully managed cloud service. neo2R detects Aura URLs
(*.databases.neo4j.io) automatically and selects the Query API
v2 — no extra configuration
is needed.
Create a free instance at https://console.neo4j.io to get your connection details.
my_aura <- startGraph( url = "https://<INSTANCEID>.databases.neo4j.io", database = "INSTANCEID", username = "INSTANCEID", password = "INSTANCEPASSWORD" ## api = "v2" is set automatically for *.databases.neo4j.io URLs )
Neo4j provides example datasets. For instance, you can connect to the movie recommendations database and query it as follows.
demo_aura <- startGraph( url = "https://demo.neo4jlabs.com:7473", database = "recommendations", username = "recommendations", password = "recommendations" ) ## Most prolific actors in the recommendations database cypher( demo_aura, 'MATCH (p:Person)-[:ACTED_IN]->(m:Movie) RETURN p.name AS actor, count(m) AS movies ORDER BY movies DESC LIMIT 5' ) |> print() ## Graph result: co-actors of Tom Hanks co_actors <- cypher( demo_aura, 'MATCH (tom:Person {name:"Tom Hanks"})-[mt:ACTED_IN]-> (m:Movie)<-[mca:ACTED_IN]-(coActor:Person) RETURN tom, m, coActor, mt, mca', result = "graph" ) co_actors$nodes |> head() |> lapply(function(n){ if(!is.null(n$properties$name)){ n$properties$name }else{ n$properties$title } })
Running Neo4j
You can download and install Neo4j according to the documentation. You can also run it in a Docker container. It takes a few seconds to start.
The following chunks show how to instantiate a Docker container running Neo4j version 3, 4, or 5. The main differences between the calls are related to the APOC library and SSL configuration.
Neo4j 3.x
#!/bin/sh ################################# ## CONFIG according to your needs ################################# export CONTAINER=neo4j_cont export NJ_VERSION=3.5.30 ## Ports export NJ_HTTP_PORT=7474 export NJ_HTTPS_PORT=7473 export NJ_BOLT_PORT=7687 ## Change the location of the Neo4j directory export NJ_HOME=~/neo4j_home ## Authorization ## set to 'none' if you want to disable authorization NJ_AUTH=neo4j/donttrustusers ## APOC download export NJ_APOC=https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.15/apoc-3.5.0.15-all.jar ################################# ## RUN ################################# mkdir -p $NJ_HOME ## Import and data directory export NJ_IMPORT=$NJ_HOME/neo4jImport mkdir -p $NJ_IMPORT export NJ_DATA=$NJ_HOME/neo4jData if test -e $NJ_DATA; then echo "$NJ_DATA directory exists ==> abort - Remove it before proceeding" >&2 exit fi mkdir -p $NJ_DATA ## SSL export NJ_SSL=${NJ_HOME}/ssl mkdir -p ${NJ_SSL}/client_policy mkdir -p ${NJ_SSL}/client_policy/revoked mkdir -p ${NJ_SSL}/client_policy/trusted openssl req -subj "/CN=localhost" -new -newkey rsa:2048 \ -days 365 -nodes -x509 \ -keyout ${NJ_SSL}/client_policy/private.key \ -out ${NJ_SSL}/client_policy/public.crt chmod -R a+rwx ${NJ_SSL} ## Neo4j plugins: APOC export NJ_PLUGINS=$NJ_HOME/neo4jPlugins mkdir -p $NJ_PLUGINS cd $NJ_PLUGINS wget --no-check-certificate $NJ_APOC cd - docker run -d \ --name $CONTAINER \ --publish=$NJ_HTTP_PORT:7474 \ --publish=$NJ_HTTPS_PORT:7473 \ --publish=$NJ_BOLT_PORT:7687 \ --env=NEO4J_dbms_memory_heap_initial__size=2G \ --env=NEO4J_dbms_memory_heap_max__size=2G \ --env=NEO4J_dbms_memory_pagecache_size=1G \ --env=NEO4J_dbms_query__cache__size=0 \ --env=NEO4J_cypher_min__replan__interval=100000000ms \ --env=NEO4J_cypher_statistics__divergence__threshold=1 \ --env=NEO4J_dbms_security_procedures_unrestricted=apoc.\\\* \ --env=NEO4J_dbms_directories_import=import \ --env NEO4J_AUTH=$NJ_AUTH \ --volume $NJ_IMPORT:/var/lib/neo4j/import \ --volume $NJ_DATA/data:/data \ --volume $NJ_PLUGINS:/plugins \ --volume=$NJ_SSL:/ssl \ --env=NEO4J_https_ssl__policy=client_policy \ --env=NEO4J_dbms_ssl_policy_client__policy_base__directory=/ssl/client_policy \ --env=NEO4J_dbms_ssl_policy_client__policy_client__auth=NONE \ --env=NEO4J_dbms_ssl_policy_client__policy_trust__all=true \ neo4j:$NJ_VERSION sleep 15 sudo chmod a+rwx $NJ_IMPORT
Neo4j 4.x
#!/bin/sh ################################# ## CONFIG according to your needs ################################# export CONTAINER=neo4j_cont export NJ_VERSION=4.4.26 ## Ports export NJ_HTTP_PORT=7474 export NJ_HTTPS_PORT=7473 export NJ_BOLT_PORT=7687 ## Change the location of the Neo4j directory export NJ_HOME=~/neo4j_home ## Authorization ## set to 'none' if you want to disable authorization NJ_AUTH=neo4j/donttrustusers ## APOC download export NJ_APOC=https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/4.4.0.3/apoc-4.4.0.3-all.jar ################################# ## RUN ################################# mkdir -p $NJ_HOME ## Import and data directory export NJ_IMPORT=$NJ_HOME/neo4jImport mkdir -p $NJ_IMPORT export NJ_DATA=$NJ_HOME/neo4jData if test -e $NJ_DATA; then echo "$NJ_DATA directory exists ==> abort - Remove it before proceeding" >&2 exit fi mkdir -p $NJ_DATA ## SSL export NJ_SSL=${NJ_HOME}/ssl mkdir -p ${NJ_SSL}/https mkdir -p ${NJ_SSL}/https/revoked mkdir -p ${NJ_SSL}/https/trusted openssl req -subj "/CN=localhost" -new -newkey rsa:2048 \ -days 365 -nodes -x509 \ -keyout ${NJ_SSL}/https/private.key \ -out ${NJ_SSL}/https/public.crt chmod -R a+rwx ${NJ_SSL} ## Neo4j plugins: APOC export NJ_PLUGINS=$NJ_HOME/neo4jPlugins mkdir -p $NJ_PLUGINS cd $NJ_PLUGINS wget --no-check-certificate $NJ_APOC cd - docker run -d \ --name $CONTAINER \ --publish=$NJ_HTTP_PORT:7474 \ --publish=$NJ_HTTPS_PORT:7473 \ --publish=$NJ_BOLT_PORT:7687 \ --env=NEO4J_dbms_memory_heap_initial__size=2G \ --env=NEO4J_dbms_memory_heap_max__size=2G \ --env=NEO4J_dbms_memory_pagecache_size=1G \ --env=NEO4J_dbms_query__cache__size=0 \ --env=NEO4J_cypher_min__replan__interval=100000000ms \ --env=NEO4J_cypher_statistics__divergence__threshold=1 \ --env=NEO4J_dbms_security_procedures_unrestricted=apoc.\\\* \ --env=NEO4J_dbms_directories_import=import \ --env NEO4J_AUTH=$NJ_AUTH \ --volume $NJ_IMPORT:/var/lib/neo4j/import \ --volume $NJ_DATA/data:/data \ --volume $NJ_PLUGINS:/plugins \ --volume=$NJ_SSL:/ssl \ --env=NEO4J_dbms_connector_https_enabled=true \ --env=NEO4J_dbms_ssl_policy_https_enabled=true \ --env=NEO4J_dbms_ssl_policy_https_base__directory=/ssl/https \ --env=NEO4J_dbms_ssl_policy_https_private__key=private.key \ --env=NEO4J_dbms_ssl_policy_https_public__certificate=public.crt \ --env=NEO4J_dbms_ssl_policy_https_client__auth=NONE \ --env=NEO4J_dbms_ssl_policy_https_trust__all=true \ neo4j:$NJ_VERSION sleep 15 sudo chmod a+rwx $NJ_IMPORT
Neo4j 5.x (>= 5.12)
In recent versions of Neo4j, it is not possible to instantiate the
Docker image with a specific username and password. The password must be
changed after Neo4j starts. Nevertheless, it is still possible to
instantiate the image without any credentials with the following
docker run parameter: --env NEO4J_AUTH=none
#!/bin/sh ################################# ## CONFIG according to your needs ################################# export CONTAINER=neo4j_cont export NJ_VERSION=5.26.26 ## Ports export NJ_HTTP_PORT=7474 export NJ_HTTPS_PORT=7473 export NJ_BOLT_PORT=7687 ## Change the location of the Neo4j directory export NJ_HOME=~/neo4j_home ## APOC download export NJ_APOC=https://github.com/neo4j/apoc/releases/download/5.26.26/apoc-5.26.26-core.jar ################################# ## RUN ################################# mkdir -p $NJ_HOME ## Import and data directory export NJ_IMPORT=$NJ_HOME/neo4jImport mkdir -p $NJ_IMPORT export NJ_DATA=$NJ_HOME/neo4jData if test -e $NJ_DATA; then echo "$NJ_DATA directory exists ==> abort - Remove it before proceeding" >&2 exit fi mkdir -p $NJ_DATA export NJ_LOGS=$NJ_HOME/neo4jLogs mkdir -p $NJ_LOGS ## SSL export NJ_SSL=${NJ_HOME}/ssl mkdir -p ${NJ_SSL}/https mkdir -p ${NJ_SSL}/https/revoked mkdir -p ${NJ_SSL}/https/trusted openssl req -subj "/CN=localhost" -new -newkey rsa:2048 \ -days 365 -nodes -x509 \ -keyout ${NJ_SSL}/https/private.key \ -out ${NJ_SSL}/https/public.crt cp ${NJ_SSL}/https/public.crt ${NJ_SSL}/https/trusted chmod -R a+rwx ${NJ_SSL} ## Neo4j plugins: APOC export NJ_PLUGINS=$NJ_HOME/neo4jPlugins mkdir -p $NJ_PLUGINS cd $NJ_PLUGINS wget --no-check-certificate $NJ_APOC cd - ## Add ` --env NEO4J_AUTH=none ` if you don't want to setup credentials docker run -d \ --name $CONTAINER \ --publish=$NJ_HTTP_PORT:7474 \ --publish=$NJ_HTTPS_PORT:7473 \ --publish=$NJ_BOLT_PORT:7687 \ --env=NEO4J_server_memory_heap_initial__size=2G \ --env=NEO4J_server_memory_heap_max__size=2G \ --env=NEO4J_server_memory_pagecache_size=1G \ --env=NEO4J_server_db_query__cache__size=0 \ --env=NEO4J_dbms_cypher_min__replan__interval=100000000ms \ --env=NEO4J_dbms_cypher_statistics__divergence__threshold=1 \ --env=NEO4J_dbms_security_procedures_unrestricted=apoc.\\\* \ --env=NEO4J_server_directories_import=import\ --volume=$NJ_IMPORT:/var/lib/neo4j/import \ --volume=$NJ_DATA/data:/data \ --volume=$NJ_LOGS:/var/lib/neo4j/logs \ --volume=$NJ_PLUGINS:/plugins \ --volume=$NJ_SSL:/ssl \ --env=NEO4J_server_https_enabled=true \ --env=NEO4J_dbms_ssl_policy_https_enabled=true \ --env=NEO4J_dbms_ssl_policy_https_base__directory=/ssl/https \ --env=NEO4J_dbms_ssl_policy_https_private__key=private.key \ --env=NEO4J_dbms_ssl_policy_https_public__certificate=public.crt \ --env=NEO4J_dbms_ssl_policy_https_client__auth=NONE \ --env=NEO4J_dbms_ssl_policy_https_trust__all=true \ neo4j:$NJ_VERSION sleep 15 sudo chmod a+rwx $NJ_IMPORT
Neo4j >= 2025
In recent versions of Neo4j, it is not possible to instantiate the
Docker image with a specific username and password. The password must be
changed after Neo4j starts. Nevertheless, it is still possible to
instantiate the image without any credentials with the following
docker run parameter: --env NEO4J_AUTH=none
#!/bin/sh ################################# ## CONFIG according to your needs ################################# export CONTAINER=neo4j_cont export NJ_VERSION=2026.06.0 ## Ports export NJ_HTTP_PORT=7474 export NJ_HTTPS_PORT=7473 export NJ_BOLT_PORT=7687 ## Change the location of the Neo4j directory export NJ_HOME=~/neo4j_home ################################# ## RUN ################################# mkdir -p $NJ_HOME ## Import and data directory export NJ_IMPORT=$NJ_HOME/neo4jImport mkdir -p $NJ_IMPORT export NJ_DATA=$NJ_HOME/neo4jData if test -e $NJ_DATA; then echo "$NJ_DATA directory exists ==> abort - Remove it before proceeding" >&2 exit fi mkdir -p $NJ_DATA export NJ_LOGS=$NJ_HOME/neo4jLogs mkdir -p $NJ_LOGS ## SSL export NJ_SSL=${NJ_HOME}/ssl mkdir -p ${NJ_SSL}/https mkdir -p ${NJ_SSL}/https/revoked mkdir -p ${NJ_SSL}/https/trusted openssl req -subj "/CN=localhost" -new -newkey rsa:2048 \ -days 365 -nodes -x509 \ -keyout ${NJ_SSL}/https/private.key \ -out ${NJ_SSL}/https/public.crt cp ${NJ_SSL}/https/public.crt ${NJ_SSL}/https/trusted chmod -R a+rwx ${NJ_SSL} ## Plugins directory (APOC jar is now bundled in the image; ## NEO4J_PLUGINS copies it in automatically at container start, ## and persisting /plugins avoids re-copying on every restart) export NJ_PLUGINS=$NJ_HOME/neo4jPlugins mkdir -p $NJ_PLUGINS ## Add ` --env NEO4J_AUTH=none ` if you don't want to setup credentials docker run -d \ --name $CONTAINER \ --publish=$NJ_HTTP_PORT:7474 \ --publish=$NJ_HTTPS_PORT:7473 \ --publish=$NJ_BOLT_PORT:7687 \ --env=NEO4J_server_memory_heap_initial__size=2G \ --env=NEO4J_server_memory_heap_max__size=2G \ --env=NEO4J_server_memory_pagecache_size=1G \ --env=NEO4J_server_db_query__cache__size=0 \ --env=NEO4J_dbms_cypher_min__replan__interval=100000000ms \ --env=NEO4J_dbms_cypher_statistics__divergence__threshold=1 \ --env=NEO4J_PLUGINS='["apoc"]' \ --env=NEO4J_dbms_security_procedures_unrestricted=apoc.\\\* \ --env=NEO4J_server_directories_import=import\ --volume=$NJ_IMPORT:/var/lib/neo4j/import \ --volume=$NJ_DATA/data:/data \ --volume=$NJ_LOGS:/var/lib/neo4j/logs \ --volume=$NJ_PLUGINS:/plugins \ --volume=$NJ_SSL:/ssl \ --env=NEO4J_server_https_enabled=true \ --env=NEO4J_dbms_ssl_policy_https_enabled=true \ --env=NEO4J_dbms_ssl_policy_https_base__directory=/ssl/https \ --env=NEO4J_dbms_ssl_policy_https_private__key=private.key \ --env=NEO4J_dbms_ssl_policy_https_public__certificate=public.crt \ --env=NEO4J_dbms_ssl_policy_https_client__auth=NONE \ --env=NEO4J_dbms_ssl_policy_https_trust__all=true \ neo4j:$NJ_VERSION sleep 15 sudo chmod a+rwx $NJ_IMPORT
Update credentials for neo4j >= 5
If you did not disable credentials (with --env NEO4J_AUTH=none),
you’ll need to first change the user password before being able to
connect to the graph database. The following chunk shows how to do it
with neo2R.
library(neo2R) system <- startGraph( "https://localhost:7473", database="system", check=FALSE, username="neo4j", password="neo4j", importPath="~/neo4j_home/neo4jImport", .opts = list(ssl_verifypeer=0) ) cypher( system, "ALTER CURRENT USER SET PASSWORD FROM 'neo4j' TO 'donttrustusers'" )
Connect to Neo4j
After installing neo4j, startGraph is used 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 import
directory has been defined in the configuration, you can specify it in
order to allow import from data.frames.
Optional: on a self-managed Neo4j >= 5.19, pass api = "v2" explicitly
to use it.
library(neo2R) graph <- startGraph( "https://localhost:7473", username="neo4j", password="donttrustusers", importPath="~/neo4j_home/neo4jImport", .opts = list(ssl_verifypeer=0) )
Import from data.frame
If you’re connected to a local instance of Neo4j and 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.
######################################### ## Nodes ## 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) } ## 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_from_df( graph=graph, cql='MERGE (n:TestNode {name:row.name, value:toFloat(row.value)})', toImport=nodes ) ######################################### ## Edges ## Define node 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_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 )
Query 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" (the “graph” method is
quite slow with version 5 of Neo4j for unknown reason).
## 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:7c67c0f3-52a6-4303-8979-b95bcb63257b:7`
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:7`$elementId
## [1] "4:7c67c0f3-52a6-4303-8979-b95bcb63257b:7"
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:7`$labels
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:7`$labels[[1]]
## [1] "TestNode"
##
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:7`$properties
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:7`$properties$name
## [1] "N 2585"
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:7`$properties$value
## [1] 1.965486
##
##
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:97347`
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:97347`$elementId
## [1] "4:7c67c0f3-52a6-4303-8979-b95bcb63257b:97347"
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:97347`$labels
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:97347`$labels[[1]]
## [1] "TestNode"
##
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:97347`$properties
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:97347`$properties$name
## [1] "V 30913"
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:97347`$properties$value
## [1] 10.389
##
##
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:13440`
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:13440`$elementId
## [1] "4:7c67c0f3-52a6-4303-8979-b95bcb63257b:13440"
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:13440`$labels
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:13440`$labels[[1]]
## [1] "TestNode"
##
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:13440`$properties
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:13440`$properties$name
## [1] "Z 33864"
##
## $nodes$`4:7c67c0f3-52a6-4303-8979-b95bcb63257b:13440`$properties$value
## [1] 5.65467
##
##
##
##
## $relationships
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543`
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543`$elementId
## [1] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543`$startNodeElementId
## [1] "4:7c67c0f3-52a6-4303-8979-b95bcb63257b:7"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543`$endNodeElementId
## [1] "4:7c67c0f3-52a6-4303-8979-b95bcb63257b:97347"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543`$type
## [1] "TestEdge"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543`$properties
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543`$properties$property
## [1] 8
##
##
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423`
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423`$elementId
## [1] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423`$startNodeElementId
## [1] "4:7c67c0f3-52a6-4303-8979-b95bcb63257b:97347"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423`$endNodeElementId
## [1] "4:7c67c0f3-52a6-4303-8979-b95bcb63257b:13440"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423`$type
## [1] "TestEdge"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423`$properties
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423`$properties$property
## [1] 0
##
##
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:470`
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:470`$elementId
## [1] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:470"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:470`$startNodeElementId
## [1] "4:7c67c0f3-52a6-4303-8979-b95bcb63257b:13440"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:470`$endNodeElementId
## [1] "4:7c67c0f3-52a6-4303-8979-b95bcb63257b:79444"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:470`$type
## [1] "TestEdge"
##
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:470`$properties
## $relationships$`5:7c67c0f3-52a6-4303-8979-b95bcb63257b:470`$properties$property
## [1] 10
##
##
##
##
## $paths
## $paths[[1]]
## [1] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543" "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423"
## [3] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:470" "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:7553"
## [5] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:94678"
##
## $paths[[2]]
## [1] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543" "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423"
## [3] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:470" "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:7553"
## [5] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:98608"
##
## $paths[[3]]
## [1] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:93543" "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:31423"
## [3] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:69425" "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:71263"
## [5] "5:7c67c0f3-52a6-4303-8979-b95bcb63257b:58428"
print(table(unlist(lapply(net$paths, length))))
##
## 5
## 945