├── .Rbuildignore
├── .github
├── .gitignore
└── workflows
│ └── check-standard.yaml
├── .gitignore
├── .travis.yml
├── DESCRIPTION
├── LICENSE
├── NAMESPACE
├── NEWS.md
├── R
├── neo4j_import.R
├── neo4j_query.R
├── neo4j_restart.R
├── neo4j_rmdir.R
├── neo4j_rmfiles.R
├── neo4j_start.R
├── neo4j_status.R
├── neo4j_stop.R
└── neo4j_wipe.R
├── README.Rmd
├── README.md
├── man
├── neo4j_import.Rd
├── neo4j_query.Rd
├── neo4j_restart.Rd
├── neo4j_rmdir.Rd
├── neo4j_rmfiles.Rd
├── neo4j_start.Rd
├── neo4j_status.Rd
├── neo4j_stop.Rd
└── neo4j_wipe.Rd
├── neo4jshell.Rproj
├── neo4jshell.png
└── vignettes
├── .gitignore
├── admin.Rmd
├── files.Rmd
└── querying.Rmd
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^\.travis\.yml$
4 | ^\.github$
5 | ^CRAN-RELEASE$
6 | ^codecov\.yml$
7 | ^cran-comments\.md$
8 | ^README\.Rmd$
9 | neo4jshell.png
10 |
--------------------------------------------------------------------------------
/.github/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
--------------------------------------------------------------------------------
/.github/workflows/check-standard.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | push:
5 | branches: [main, master]
6 | pull_request:
7 | branches: [main, master]
8 |
9 | name: R-CMD-check
10 |
11 | jobs:
12 | R-CMD-check:
13 | runs-on: ${{ matrix.config.os }}
14 |
15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
16 |
17 | strategy:
18 | fail-fast: false
19 | matrix:
20 | config:
21 | - {os: macOS-latest, r: 'release'}
22 | - {os: windows-latest, r: 'release'}
23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
24 | - {os: ubuntu-latest, r: 'release'}
25 | - {os: ubuntu-latest, r: 'oldrel-1'}
26 |
27 | env:
28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
29 | R_KEEP_PKG_SOURCE: yes
30 |
31 | steps:
32 | - uses: actions/checkout@v2
33 |
34 | - name: Install libssh-dev
35 | if: runner.os == 'Linux'
36 | run: sudo apt-get install -y libssh-dev
37 |
38 | - uses: r-lib/actions/setup-pandoc@v2
39 |
40 | - uses: r-lib/actions/setup-r@v1
41 | with:
42 | r-version: ${{ matrix.config.r }}
43 | http-user-agent: ${{ matrix.config.http-user-agent }}
44 | use-public-rspm: true
45 |
46 | - uses: r-lib/actions/setup-r-dependencies@v1
47 | with:
48 | extra-packages: rcmdcheck
49 |
50 | - uses: r-lib/actions/setup-tinytex@v2
51 | - uses: r-lib/actions/check-r-package@v1
52 |
53 | - name: Show testthat output
54 | if: always()
55 | run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true
56 | shell: bash
57 |
58 | - name: Upload check results
59 | if: failure()
60 | uses: actions/upload-artifact@main
61 | with:
62 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results
63 | path: check
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 | inst/doc
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r
2 |
3 | language: R
4 | cache: packages
5 |
6 | before_install:
7 | - sudo apt-get -y install libssh-dev
8 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: neo4jshell
2 | Type: Package
3 | Title: Querying and Managing 'Neo4J' Databases in 'R'
4 | Version: 0.1.2.9000
5 | Authors@R:
6 | c(person(given = "Keith",
7 | family = "McNulty",
8 | role = c("cre", "aut", "cph"),
9 | email = "keith.mcnulty@gmail.com",
10 | comment = c(ORCID = "0000-0002-2332-1654")),
11 | person(given = "Liz",
12 | family = "Romero",
13 | role = c("ctb"),
14 | email = "liz.romero357@gmail.com"))
15 | Description: Sends queries to a specified 'Neo4J' graph database, capturing results in a dataframe where appropriate.
16 | Other useful functions for the importing and management of data on the 'Neo4J' server and basic local server admin.
17 | License: MIT + file LICENSE
18 | Encoding: UTF-8
19 | LazyData: true
20 | Imports:
21 | magrittr,
22 | ssh,
23 | sys,
24 | fs,
25 | R.utils
26 | RoxygenNote: 7.1.1
27 | Suggests:
28 | knitr,
29 | rmarkdown
30 | SystemRequirements:
31 | neo4j - http://www.neo4j.com,
32 | cypher-shell - https://github.com/neo4j/cypher-shell/releases
33 | VignetteBuilder: knitr
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2019
2 | COPYRIGHT HOLDER: Keith McNulty
3 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | exportPattern("^[[:alpha:]]+")
2 | importFrom("utils", "read.csv", "write.csv", "untar", "unzip")
3 | importFrom("magrittr", "%>%")
4 |
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | # neo4jshell 0.1.1
2 |
3 | * Added a `NEWS.md` file to track changes to the package.
4 | * Addressed problematic data type guessing in neo4j_query by pulling all data as character (#10).
5 |
6 | # neo4jshell 0.1.2
7 |
8 | * Fixed a bug that returned unexpected output shape for single row results from `neo4j_query()`.
9 |
10 | # neo4jshell 0.1.2.9000
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/R/neo4j_import.R:
--------------------------------------------------------------------------------
1 | #' Imports a csv or a compressed file to Neo4J import folder.
2 | #'
3 | #' @param local Logical indicating whether import is to a locally hosted or a remotely hosted server.
4 | #' @param con If remotely hosted server, list containing three objects: address, uid, pwd as character strings providing connection to the Neo4J server.
5 | #' uid and pwd must be for an account on the server with appropriate permissions.
6 | #' @param source Character string of local path to the csv, zip or tar.gz compressed csv file to be imported
7 | #' @param import_dir Character string of full path to the Neo4J import directory
8 | #' @param gunzip_path Path to gunzip on the local or remote server to be passed to the system command following import if necessary.
9 | #' @param tar_path Path to tar on the local or remote server to be passed to the system command following import if necessary.
10 | #' @param unzip_path Path to unzip on the local or remote server to be passed to the system command if necessary.
11 | #'
12 | #' @return System messages confirming success or error. zip or tar files will be removed after import and decompression.
13 | #'
14 | #' @examples
15 | #' # import zip to local import directory, with zip in the local system PATH variable
16 | #' write.csv(mtcars, "mtcars.csv")
17 | #' zip("mtcars.zip", "mtcars.csv")
18 | #' fs::dir_create("import")
19 | #' neo4j_import(local = TRUE, source = "mtcars.zip")
20 | #' fs::file_delete("mtcars.zip")
21 | #' fs::file_delete("mtcars.csv")
22 | #' fs::dir_delete("import")
23 |
24 |
25 |
26 | neo4j_import <- function (local = FALSE, con = list(address = NULL, uid = NULL, pwd = NULL), source = NULL,
27 | import_dir = "import", unzip_path = "unzip",
28 | gunzip_path = "gunzip", tar_path = "tar") {
29 |
30 |
31 | if (substr(import_dir, nchar(import_dir), nchar(import_dir)) != "/") {
32 | import_dir <- paste0(import_dir, "/")
33 | }
34 |
35 | tmp1 <- tempfile()
36 | tmp2 <- tempfile()
37 | tmp3 <- tempfile()
38 | tmp4 <- tempfile()
39 |
40 | if (local == FALSE) {
41 |
42 | base_address <- basename(con$address)
43 | if (grepl(":", base_address)) {
44 | base_address <- gsub(":(.*)", "", base_address)
45 | }
46 |
47 | ssh_uid <- paste0(con$uid, "@", base_address)
48 |
49 | if (substr(source, nchar(source) - 3, nchar(source)) == ".csv") {
50 | session <- ssh::ssh_connect(ssh_uid, passwd = con$pwd)
51 | ssh::scp_upload(session, source, to = import_dir)
52 | ssh::ssh_disconnect(session)
53 | message("Import successful!")
54 | } else if (substr(source, nchar(source) - 3, nchar(source)) == ".zip") {
55 | session <- ssh::ssh_connect(ssh_uid, passwd = con$pwd)
56 | ssh::scp_upload(session, source, to = import_dir)
57 | output1 <- ssh::ssh_exec_wait(session, paste(unzip_path, "-o", paste0(import_dir, basename(source)), "-d", import_dir), std_err = tmp1)
58 | output2 <- ssh::ssh_exec_wait(session, paste("rm", paste0(import_dir, basename(source))), std_err = tmp2)
59 | ssh::ssh_disconnect(session)
60 | if (output1 == 0 & output2 == 0) {
61 | message("Import and unzip successful! Zip file has been removed!")
62 | } else {
63 | c(readLines(tmp1), readLines(tmp2)) %>% paste(collapse = " ") %>% noquote() %>% stop(call. = FALSE)
64 | }
65 | } else if (substr(source, nchar(source) - 6, nchar(source)) == ".tar.gz") {
66 | session <- ssh::ssh_connect(ssh_uid, passwd = con$pwd)
67 | ssh::scp_upload(session, source, to = import_dir)
68 | output1 <- ssh::ssh_exec_wait(session, paste(gunzip_path, "-f", paste0(import_dir, basename(source))), std_err = tmp1)
69 | output2 <- ssh::ssh_exec_wait(session, paste(tar_path, "-C", import_dir, "-xvf", paste0(import_dir, gsub(".gz", "", basename(source)))), std_err = tmp2)
70 | output3 <- ssh::ssh_exec_wait(session, paste("rm", paste0(import_dir, gsub(".gz", "", basename(source)))), std_err = tmp3)
71 | ssh::ssh_disconnect(session)
72 | if (output1 == 0 & output2 == 0 & output3 == 0) {
73 | message("Import and gunzip successful! Tar file has been removed!")
74 | } else {
75 | c(readLines(tmp1), readLines(tmp2), readLines(tmp3)) %>% paste(collapse = " ") %>% noquote() %>% stop(call. = FALSE)
76 | }
77 | } else {
78 | stop("Source is not a .csv, .zip or a .tar.gz file.")
79 | }
80 |
81 | } else {
82 |
83 | if (substr(source, nchar(source) - 3, nchar(source)) == ".csv") {
84 | new <- paste0(import_dir, basename(source))
85 | fs::file_copy(source, new, overwrite = TRUE)
86 | message("Import successful!")
87 | } else if (substr(source, nchar(source) - 3, nchar(source)) == ".zip") {
88 | new <- paste0(import_dir, basename(source))
89 | fs::file_copy(source, new, overwrite = TRUE)
90 | unzip(new, exdir = import_dir, unzip = unzip_path)
91 | fs::file_delete(new)
92 | message("Import and unzip successful! Zip file has been removed!")
93 | } else if (substr(source, nchar(source) - 6, nchar(source)) == ".tar.gz") {
94 | new <- paste0(import_dir, basename(source))
95 | fs::file_copy(source, new, overwrite = TRUE)
96 | R.utils::gunzip(new)
97 | untar(gsub(".gz", "", new), exdir = import_dir, tar = tar_path)
98 | fs::file_delete(gsub(".gz", "", new))
99 | message("Import and gunzip successful! Tar file has been removed!")
100 | } else {
101 | stop("Source is not a .csv, .zip or a .tar.gz file.")
102 | }
103 |
104 | }
105 | }
106 |
107 |
--------------------------------------------------------------------------------
/R/neo4j_query.R:
--------------------------------------------------------------------------------
1 | #' Execute a query string in Neo4J using cypher-shell and capture output
2 | #'
3 | #' @param con List containing three objects: bolt address, uid, pwd as character strings providing connection to the Neo4J server
4 | #' @param qry Character string of the query or queries to be sent to Neo4J. Read queries should be single queries.
5 | #' @param shell_path If cypher-shell is not in the PATH system variable, the full local path to cypher-shell executable.
6 | #' @param database The name of the database if other than the default database. (For multi-tenancy installations).
7 | #' @param encryption Passes encryption argument to cypher-shell if necessary. Older versions of cypher-shell may require 'true' or 'false' to be passed.
8 | #'
9 | #' @return A dataframe of results if the read query is successful. A text string if an error is encountered.
10 | #' Write queries will return a zero length response if successful.
11 | #' If multiple read queries were submitted, only the results of the final query will be returned.
12 | #'
13 | #' @examples
14 | #' # if neo4j exists, start the local server, give it a moment to fire up, and run a query
15 | #' if (nzchar(Sys.which("neo4j"))) {
16 | #' neo4j_start()
17 | #' Sys.sleep(2)
18 | #' graph <- list(address = "bolt://localhost:7687", uid = "neo4j", pwd = "password")
19 | #' neo4j_query(con = graph, qry = "MATCH (n) RETURN (n)")
20 | #' }
21 |
22 |
23 |
24 | neo4j_query <- function(con = list(address = NULL, uid = NULL, pwd = NULL), qry = NULL,
25 | shell_path = "cypher-shell", database = NULL, encryption = c("default", "true", "false")) {
26 |
27 | encryption <- match.arg(encryption)
28 |
29 | qry <- gsub("\n", " ", qry)
30 | qry <- gsub("\t", "", qry)
31 | qry <- gsub("^\\s+|\\s+$", "", qry)
32 |
33 | # remove trailing ;
34 |
35 | if (substr(qry, nchar(qry), nchar(qry)) == ";") {
36 | qry <- substr(qry, 1, nchar(qry) - 1)
37 | }
38 |
39 | # split multiple queries into single queries inside a vector (command line cypher-shell only accepts one query at a time)
40 |
41 | if (grepl(";", qry)) {
42 | qry <- strsplit(qry, ";")
43 | qry <- as.vector(qry[[1]])
44 | } else {
45 | qry <- as.vector(qry)
46 | }
47 |
48 | # execute queries
49 |
50 | for (i in 1:length(qry)) {
51 | if (!is.null(database)) {
52 | assign(paste0("args_", i),
53 | c("-a", con$address,
54 | "-u", con$uid,
55 | "-p", con$pwd,
56 | "-d", database,
57 | "--encryption", encryption,
58 | qry[i]) %>%
59 | noquote()
60 | )
61 | } else {
62 | assign(paste0("args_", i),
63 | c("-a", con$address,
64 | "-u", con$uid,
65 | "-p", con$pwd,
66 | "--encryption", encryption,
67 | qry[i]) %>%
68 | noquote()
69 | )
70 | }
71 |
72 | assign(paste0("tmp1_", i), tempfile())
73 | assign(paste0("tmp2_", i), tempfile())
74 | }
75 |
76 | for (i in 1:length(qry)) {
77 | assign(paste0("output_", i),
78 | sys::exec_wait(shell_path,
79 | args = get(paste0("args_", i)),
80 | std_out = get(paste0("tmp1_", i)),
81 | std_err = get(paste0("tmp2_", i))
82 | )
83 | )
84 | }
85 |
86 | # gather output statuses in vector
87 |
88 | if (length(qry) == 1) {
89 | output <- get(paste0("output_", 1))
90 | } else {
91 | output <- get(paste0("output_", 1))
92 | for (k in 2:length(qry)) {
93 | output <- c(output, get(paste0("output_", i)))
94 | }
95 | }
96 |
97 |
98 |
99 | tmp_final <- tempfile()
100 |
101 | # if all queries successful, write results of final query or confirm zero-length response
102 | if (sum(output) == 0) {
103 | tmp <- readLines(get(paste0("tmp1_", length(qry))))
104 | if (length(tmp) > 0) {
105 | tmp <- gsub("(?:\\G(?!^)|\\[)[^][,]*\\K,(?=[^][]*])", ";;;", tmp, perl = TRUE) # deal with embedded [] lists for read.csv
106 | tmp <- gsub("(?:\\G(?!^)|\\{)[^{},]*\\K,(?=[^{}]*})", ";;;", tmp, perl = TRUE) # deal with embedded {} lists for read.csv
107 | write(tmp, tmp_final)
108 | r <- read.csv(tmp_final, colClasses = "character", strip.white = TRUE)
109 | r <- lapply(r, function (x) gsub(";;;", ",", x))
110 | as.data.frame(r, stringsAsFactors = FALSE)
111 | } else {
112 | message("Query succeeded with a zero length response from Neo4J")
113 | }
114 | } else {
115 | # if any error occurred, show all responses from Neo4J
116 | if (length(qry) == 1) {
117 | readLines(get("tmp2_1")) %>% paste(collapse = " ") %>% noquote() %>% stop(call. = FALSE)
118 | } else {
119 | tmpvec <- readLines(get("tmp2_1"))
120 | for (w in 2:length(qry)) {
121 | tmpvec <- c(tmpvec, readLines(get(paste0("tmp2_", w))))
122 | }
123 | tmpvec %>% paste(collapse = " ") %>% noquote() %>% stop(call. = FALSE)
124 | }
125 |
126 | }
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/R/neo4j_restart.R:
--------------------------------------------------------------------------------
1 | #' Restart a local Neo4J database
2 | #'
3 | #' @param neo4j_path Path to the Neo4J executable (usually in the bin directory of the Neo4J installation)
4 | #'
5 | #' @return System messages
6 | #'
7 | #' @examples
8 | #' # if neo4j exists, restart local graph with neo4j executable in the system PATH variable
9 | #' if (nzchar(Sys.which("neo4j"))) {
10 | #' neo4j_restart()
11 | #' }
12 |
13 |
14 | neo4j_restart <- function(neo4j_path = "neo4j") {
15 | sys::exec_wait(neo4j_path, "restart")
16 | }
17 |
--------------------------------------------------------------------------------
/R/neo4j_rmdir.R:
--------------------------------------------------------------------------------
1 | #' Remove subdirectory and all its contents from the Neo4J import directory
2 | #'
3 | #' @param local Logical indicating whether import is to a locally hosted or remotely hosted server.
4 | #' @param con If remotely hosted server, list containing three objects: address, uid, pwd as character strings providing connection to the Neo4J server.
5 | #' uid and pwd must be for an account on the server with appropriate permissions.
6 | #' @param dir Character string of the Neo4J import subdirectory name to be deleted.
7 | #' @param import_dir Character string of path to the Neo4J import directory.
8 | #'
9 | #' @return A success message if successful. A error message otherwise.
10 | #'
11 | #' @examples
12 | #' # remove a subdirectory and all its contents from the local import directory
13 | #' fs::dir_create("import/data")
14 | #' fs::file_create("import/data/data.csv")
15 | #' neo4j_rmdir(local = TRUE, dir = "data", import_dir = "import")
16 | #' fs::dir_delete("import")
17 |
18 |
19 |
20 | neo4j_rmdir <- function (local = FALSE, con = list(address = NULL, uid = NULL, pwd = NULL), dir = NULL, import_dir = "import") {
21 |
22 | if (substr(import_dir, nchar(import_dir), nchar(import_dir)) != "/") {
23 | import_dir <- paste0(import_dir, "/")
24 | }
25 |
26 | filestring <- paste0(import_dir, dir)
27 | tmp1 <- tempfile()
28 |
29 | if (local == FALSE) {
30 |
31 | base_address <- basename(con$address)
32 | if (grepl(":", base_address)) {
33 | base_address <- gsub(":(.*)", "", base_address)
34 | }
35 |
36 | ssh_uid <- paste0(con$uid, "@", base_address)
37 | session <- ssh::ssh_connect(ssh_uid, passwd = con$pwd)
38 | output <- ssh::ssh_exec_wait(session, command = paste("rm -r", filestring), std_err = tmp1)
39 | ssh::ssh_disconnect(session)
40 |
41 | if (output == 0) {
42 | message("Directory and all contents removed successfully!")
43 | } else {
44 | readLines(tmp1) %>% paste(collapse = " ") %>% noquote() %>% stop(call. = FALSE)
45 | }
46 |
47 | } else {
48 |
49 | fs::dir_delete(filestring)
50 | message("Directory and all contents removed successfully!")
51 |
52 | }
53 |
54 |
55 |
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/R/neo4j_rmfiles.R:
--------------------------------------------------------------------------------
1 | #' Remove files from the Neo4J import directory
2 | #'
3 | #' @param local Logical indicating whether import is to a locally hosted or remotely hosted server.
4 | #' @param con If remotely hosted server, list containing three objects: address, uid, pwd as character strings providing connection to the Neo4J server.
5 | #' uid and pwd must be for an account on the server with appropriate permissions.
6 | #' @param files Character vector of file names to be removed.
7 | #' @param import_dir Character string of path to the Neo4J import directory.
8 | #'
9 | #' @return A success message if successful. An error message otherwise.
10 | #'
11 | #' @examples
12 | #' # remove file from local import directory
13 | #' fs::dir_create("import")
14 | #' fs::file_create("import/data.csv")
15 | #' neo4j_rmfiles(local = TRUE, files = "data.csv", import_dir = "import")
16 | #' fs::dir_delete("import")
17 |
18 |
19 |
20 | neo4j_rmfiles <- function (local = FALSE, con = list(address = NULL, uid = NULL, pwd = NULL), files = NULL, import_dir = "import") {
21 |
22 | if (substr(import_dir, nchar(import_dir), nchar(import_dir)) != "/") {
23 | import_dir <- paste0(import_dir, "/")
24 | }
25 |
26 | files <- paste0(import_dir, files)
27 | filestring <- paste(files, collapse = " ")
28 | tmp1 <- tempfile()
29 |
30 | if (local == FALSE) {
31 |
32 | base_address <- basename(con$address)
33 | if (grepl(":", base_address)) {
34 | base_address <- gsub(":(.*)", "", base_address)
35 | }
36 |
37 | ssh_uid <- paste0(con$uid, "@", base_address)
38 | session <- ssh::ssh_connect(ssh_uid, passwd = con$pwd)
39 | output <- ssh::ssh_exec_wait(session, command = paste("rm", filestring), std_err = tmp1)
40 | ssh::ssh_disconnect(session)
41 |
42 | if (output == 0) {
43 | message("Files removed successfully!")
44 | } else {
45 | readLines(tmp1) %>% paste(collapse = " ") %>% noquote() %>% stop(call. = FALSE)
46 | }
47 |
48 | } else {
49 |
50 | fs::file_delete(files)
51 | message("Files removed successfully!")
52 |
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/R/neo4j_start.R:
--------------------------------------------------------------------------------
1 | #' Start a local Neo4J database
2 | #'
3 | #' @param neo4j_path Path to the Neo4J executable (usually in the bin directory of the Neo4J installation)
4 | #'
5 | #' @return System messages
6 | #'
7 | #' @examples
8 | #' # if neo4j exists, start local graph on with neo4j executable in the system PATH variable
9 | #' if (nzchar(Sys.which("neo4j"))) {
10 | #' neo4j_start()
11 | #' }
12 |
13 |
14 |
15 | neo4j_start <- function(neo4j_path = "neo4j") {
16 | sys::exec_wait(neo4j_path, "start")
17 | }
18 |
--------------------------------------------------------------------------------
/R/neo4j_status.R:
--------------------------------------------------------------------------------
1 | #' Check status of a local Neo4J database
2 | #'
3 | #' @param neo4j_path Path to the Neo4J executable (usually in the bin directory of the Neo4J installation)
4 | #'
5 | #' @return System messages
6 | #'
7 | #' @examples
8 | #' # if neo4j exists, check status local graph with neo4j executable in the system PATH variable
9 | #' if (nzchar(Sys.which("neo4j"))) {
10 | #' neo4j_status()
11 | #' }
12 |
13 |
14 | neo4j_status <- function(neo4j_path = "neo4j") {
15 | sys::exec_wait(neo4j_path, "status")
16 | }
17 |
--------------------------------------------------------------------------------
/R/neo4j_stop.R:
--------------------------------------------------------------------------------
1 | #' Stop a local Neo4J database
2 | #'
3 | #' @param neo4j_path Path to the Neo4J executable (usually in the bin directory of the Neo4J installation)
4 | #'
5 | #' @return System messages
6 | #'
7 | #' @examples
8 | #' # if neo4j exists, stop local graph with neo4j executable in the system PATH variable
9 | #' if (nzchar(Sys.which("neo4j"))) {
10 | #' neo4j_stop()
11 | #' }
12 |
13 |
14 | neo4j_stop <- function(neo4j_path = "neo4j") {
15 | sys::exec_wait(neo4j_path, "stop")
16 | }
17 |
--------------------------------------------------------------------------------
/R/neo4j_wipe.R:
--------------------------------------------------------------------------------
1 | #' Wipe a complete local graph database in Neo4J
2 | #'
3 | #' @param database Name of local graph database directory to wipe.
4 | #' @param data_path Path to the local Neo4J data directory
5 | #'
6 | #' @return Success or error message
7 | #'
8 | #' @examples
9 | #' # wipe database directory
10 | #' fs::dir_create("data/databases/foo")
11 | #' neo4j_wipe(database = "foo", data_path = "data")
12 | #' fs::dir_delete("data")
13 |
14 | neo4j_wipe <- function(database = NULL, data_path = NULL) {
15 | if (substr(data_path, nchar(data_path), nchar(data_path)) != "/") {
16 | data_path <- paste0(data_path, "/")
17 | }
18 |
19 | fs::dir_delete(paste0(data_path, "databases/", database))
20 | message("Graph wiped successfully!")
21 | }
22 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 |
6 |
7 | ```{r, include = FALSE}
8 | knitr::opts_chunk$set(
9 | collapse = TRUE,
10 | comment = "#>",
11 | fig.path = "man/figures/README-",
12 | out.width = "100%"
13 | )
14 |
15 | ```
16 |
17 | # neo4jshell
18 |
19 |
20 | [](https://www.tidyverse.org/lifecycle/#experimental)
21 | [](https://CRAN.R-project.org/package=neo4jshell)
22 | [](https://cran.r-project.org/package=neo4jshell)
23 | [](https://github.com/keithmcnulty/neo4jshell/actions)
24 | [](https://travis-ci.com/keithmcnulty/neo4jshell)
25 |
26 |
27 | The goal of neo4jshell is to provide rapid querying of 'Neo4J' graph databases by offering a programmatic interface with 'cypher-shell'. A wide variety of other functions are offered that allow importing and management of data files for local and remote servers, as well as simple administration of local servers for development purposes.
28 |
29 | ## Pre-installation notes
30 | This package requires the `ssh` package for interacting with remote 'Neo4J' databases, which requires `libssh` to be installed. See the vignettes for the `ssh` package [here](https://CRAN.R-project.org/package=ssh) for more details.
31 |
32 | This package also requires the 'cypher-shell' executable to be available **locally**. This is installed as standard in 'Neo4J' installations and can usually be found in the `bin` directory of that installation. It can also be installed standalone using Homebrew or is available here: https://github.com/neo4j/cypher-shell.
33 |
34 | It is recommended, for ease of use, that the path to the 'cypher-shell' executable is added to your `PATH` environment variable. If not, you should record its location for use in some of the functions within this package.
35 |
36 |
37 | ## Installation
38 |
39 | You can install the released version of neo4jshell from [CRAN](https://CRAN.R-project.org) with:
40 |
41 | ``` r
42 | install.packages("neo4jshell")
43 | ```
44 |
45 | And the development version from [GitHub](https://github.com/) with:
46 |
47 | ``` r
48 | # install.packages("devtools")
49 | devtools::install_github("keithmcnulty/neo4jshell")
50 | ```
51 |
52 | ## Functionality
53 |
54 | ### Query
55 |
56 | `neo4j_query()` sends queries to the specified 'Neo4J' graph database and, where appropriate, retrieves the results in a dataframe.
57 |
58 | In this example, the movies dataset has been started locally in the 'Neo4J' browser, with a user created that has the credentials indicated. `cypher-shell` is in the local system path.
59 |
60 | ``` {r, message = FALSE, warning = FALSE}
61 | library(neo4jshell)
62 | library(dplyr)
63 | library(tibble)
64 | ```
65 | ```{r}
66 | # set credentials (no port required in bolt address)
67 | neo_movies <- list(address = "bolt://localhost", uid = "neo4j", pwd = "password")
68 |
69 | # find directors of movies with Kevin Bacon as actor
70 | CQL <- 'MATCH (p1:Person {name: "Kevin Bacon"})-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(p2:Person)
71 | RETURN p2.name, m.title;'
72 |
73 | # run query
74 | neo4j_query(con = neo_movies, qry = CQL)
75 |
76 | ```
77 |
78 | Older versions of 'Neo4J' and 'cypher-shell' (<4.0) will require the `encryption` argument to be explicitly `'true'` or `'false'`. For newer versions, which have multi-tenancy, you can use the `database` argument to specify the database to query.
79 |
80 | ### Server management
81 |
82 | - `neo4j_import()` imports a csv, zip or tar.gz file from a local source into the specified 'Neo4J' import directory, uncompresses compressed files and removes the original compressed file as clean up.
83 | - `neo4j_rmfiles()` removes specified files from specified 'Neo4J' import directory
84 | - `neo4j_rmdir()` removes entire specified subdirectories from specified 'Neo4J' import directory
85 |
86 | ### Remote development
87 |
88 | In this general example, we can see how these functions can be used for smooth ETL to a remote 'Neo4J' server. This example assumes that the URL of the server that hosts the 'Neo4J' database is the same as the bolt URL for the 'Neo4J' database. If not, a different set of credentials will be needed for using `neo4j_import()`.
89 |
90 | ```
91 | # credentials (note no port required in server address)
92 | neo_server <- list(address = "bolt://neo.server.address", uid = "neo4j", pwd = "password")
93 |
94 | # csv data file to be loaded onto 'Neo4J' server (path relative to current working directory)
95 | datafile <- "data.csv"
96 |
97 | # CQL query to write data from datafile to 'Neo4J'
98 | loadcsv_CQL <- "LOAD CSV FROM 'file:///data.csv' etc etc;"
99 |
100 | # path to import directory on remote 'Neo4J' server (should be relative to user home directory on remote server)
101 | impdir <- "./import"
102 |
103 | # import data
104 | neo4jshell::neo4j_import(con = neo_server, source = datafile, import_dir = impdir)
105 |
106 | # write data to 'Neo4J' (assumes cypher-shell is in system PATH variable)
107 | neo4jshell:neo4j_query(con = neo_server, qry = loadcsv_CQL)
108 |
109 | # remove data file as clean-up
110 | neo4jshell::neo4j_rmfiles(con = neo_server, files = datafile, import_dir = impdir)
111 |
112 | ```
113 | In Windows, the 'cypher-shell' executable may need to be specified with the file extension, for example `shell_path = "cypher-shell.bat"`.
114 |
115 | ### Local Development
116 |
117 | If you are working with the 'Neo4J' server locally, below will help you get started.
118 |
119 | First, the code below is relative to user and is using 'Neo4J 4.0.4 Community' installed at my user's root. The directory containing the 'cypher-shell' and 'neo4j' executables are in my system's PATH environment variables.
120 |
121 | ``` {r}
122 | ## start the local server
123 | neo4j_start()
124 |
125 | ## setup connection credentials and import directory location
126 | neo_con <- list(address = "bolt://localhost:7687", uid = "neo4j", pwd = "password")
127 | import_loc <- path.expand("~/neo4j-community-4.0.4/import/")
128 | ```
129 |
130 | First we save `mtcars` to a `.csv` file, and we compress that file. This package supports a number of delivery formats, but we use a `.zip` file as an example.
131 |
132 | ```{r}
133 | mtcars <- mtcars %>%
134 | tibble::rownames_to_column(var = "model")
135 |
136 | write.csv(mtcars, "mtcars.csv", row.names = FALSE)
137 | zip("mtcars.zip", "mtcars.csv")
138 | ```
139 |
140 | Now we use `neo4j_import()` to place a **copy** of this file within the import directory you defined in `import_loc` above.
141 |
142 | ```{r}
143 | neo4j_import(local = TRUE, graph, source = "mtcars.zip", import_dir = import_loc)
144 | ```
145 |
146 | We now write a CQL query to write some information from `mtcars.csv` to the graph, and execute that query.
147 |
148 | ```{r}
149 | CQL <- "LOAD CSV WITH HEADERS FROM 'file:///mtcars.csv' AS row
150 | WITH row WHERE row.model IS NOT NULL
151 | MERGE (c:Car {name: row.model});"
152 |
153 | neo4j_query(neo_con, CQL)
154 |
155 | ```
156 |
157 |
158 | Now, let's remove the `mtcars.csv` file from the import directory of our local server as cleanup. If you want to use a sub-directory to help manage your files during an ETL into 'Neo4J', you can remove that local sub-directory when your process has completed using `neo4j_rmdir()`.
159 |
160 | ```{r}
161 | ## remove the file
162 | neo4j_rmfiles(local = TRUE, graph, files="mtcars.csv", import_dir = import_loc)
163 | ```
164 |
165 | Now let's run a query to check the data was loaded to the graph.
166 |
167 | ```{r}
168 | CQL <- "MATCH (c:Car) RETURN c.name as name LIMIT 5;"
169 |
170 | neo4j_query(neo_con, CQL)
171 |
172 | ```
173 |
174 |
175 |
176 | ### Local server administration and control
177 |
178 | - `neo4j_start()` starts a local 'Neo4J' instance
179 | - `neo4j_stop()` stops a local 'Neo4J' instance
180 | - `neo4j_restart()` restarts a local 'Neo4J' instance
181 | - `neo4j_status()` returns the status of a local 'Neo4J' instance
182 | - `neo4j_wipe()` wipes an entire graph from a local 'Neo4J' instance
183 |
184 |
185 | For example:
186 |
187 | ```{r}
188 |
189 | # my server was already running, confirm
190 | neo4j_status()
191 |
192 | # stop the server
193 | neo4j_stop()
194 |
195 | # restart
196 | neo4j_start()
197 |
198 | # give it a few seconds to fire up
199 | Sys.sleep(10)
200 |
201 | # query again
202 | neo4j_query(neo_con, qry="MATCH (c:Car) RETURN c.name as name LIMIT 5;")
203 | ```
204 |
205 | If you are using an admin account and you are using 'Neo4J 4+' you can check what databases are available by querying the system database.
206 |
207 | ```{r}
208 | neo4j_query(neo_con, qry="SHOW DATABASES;", database = "system")
209 | ```
210 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # neo4jshell
5 |
6 |
7 |
8 | [](https://lifecycle.r-lib.org/articles/stages.html#experimental)
10 | [](https://CRAN.R-project.org/package=neo4jshell)
12 | [](https://cran.r-project.org/package=neo4jshell)
14 | [](https://github.com/keithmcnulty/neo4jshell/actions)
16 | [](https://app.travis-ci.com/keithmcnulty/neo4jshell)
18 |
19 |
20 | The goal of neo4jshell is to provide rapid querying of ‘Neo4J’ graph
21 | databases by offering a programmatic interface with ‘cypher-shell’. A
22 | wide variety of other functions are offered that allow importing and
23 | management of data files for local and remote servers, as well as simple
24 | administration of local servers for development purposes.
25 |
26 | ## Pre-installation notes
27 |
28 | This package requires the `ssh` package for interacting with remote
29 | ‘Neo4J’ databases, which requires `libssh` to be installed. See the
30 | vignettes for the `ssh` package
31 | [here](https://CRAN.R-project.org/package=ssh) for more details.
32 |
33 | This package also requires the ‘cypher-shell’ executable to be available
34 | **locally**. This is installed as standard in ‘Neo4J’ installations and
35 | can usually be found in the `bin` directory of that installation. It can
36 | also be installed standalone using Homebrew or is available here:
37 | .
38 |
39 | It is recommended, for ease of use, that the path to the ‘cypher-shell’
40 | executable is added to your `PATH` environment variable. If not, you
41 | should record its location for use in some of the functions within this
42 | package.
43 |
44 | ## Installation
45 |
46 | You can install the released version of neo4jshell from
47 | [CRAN](https://CRAN.R-project.org) with:
48 |
49 | ``` r
50 | install.packages("neo4jshell")
51 | ```
52 |
53 | And the development version from [GitHub](https://github.com/) with:
54 |
55 | ``` r
56 | # install.packages("devtools")
57 | devtools::install_github("keithmcnulty/neo4jshell")
58 | ```
59 |
60 | ## Functionality
61 |
62 | ### Query
63 |
64 | `neo4j_query()` sends queries to the specified ‘Neo4J’ graph database
65 | and, where appropriate, retrieves the results in a dataframe.
66 |
67 | In this example, the movies dataset has been started locally in the
68 | ‘Neo4J’ browser, with a user created that has the credentials
69 | indicated. `cypher-shell` is in the local system path.
70 |
71 | ``` r
72 | library(neo4jshell)
73 | library(dplyr)
74 | library(tibble)
75 | ```
76 |
77 | ``` r
78 | # set credentials (no port required in bolt address)
79 | neo_movies <- list(address = "bolt://localhost", uid = "neo4j", pwd = "password")
80 |
81 | # find directors of movies with Kevin Bacon as actor
82 | CQL <- 'MATCH (p1:Person {name: "Kevin Bacon"})-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(p2:Person)
83 | RETURN p2.name, m.title;'
84 |
85 | # run query
86 | neo4j_query(con = neo_movies, qry = CQL)
87 | #> p2.name m.title
88 | #> 1 Ron Howard Frost/Nixon
89 | #> 2 Rob Reiner A Few Good Men
90 | #> 3 Ron Howard Apollo 13
91 | ```
92 |
93 | Older versions of ‘Neo4J’ and ‘cypher-shell’ (\<4.0) will require the
94 | `encryption` argument to be explicitly `'true'` or `'false'`. For newer
95 | versions, which have multi-tenancy, you can use the `database` argument
96 | to specify the database to query.
97 |
98 | ### Server management
99 |
100 | - `neo4j_import()` imports a csv, zip or tar.gz file from a local
101 | source into the specified ‘Neo4J’ import directory, uncompresses
102 | compressed files and removes the original compressed file as clean
103 | up.
104 | - `neo4j_rmfiles()` removes specified files from specified ‘Neo4J’
105 | import directory
106 | - `neo4j_rmdir()` removes entire specified subdirectories from
107 | specified ‘Neo4J’ import directory
108 |
109 | ### Remote development
110 |
111 | In this general example, we can see how these functions can be used for
112 | smooth ETL to a remote ‘Neo4J’ server. This example assumes that the URL
113 | of the server that hosts the ‘Neo4J’ database is the same as the bolt
114 | URL for the ‘Neo4J’ database. If not, a different set of credentials
115 | will be needed for using `neo4j_import()`.
116 |
117 | # credentials (note no port required in server address)
118 | neo_server <- list(address = "bolt://neo.server.address", uid = "neo4j", pwd = "password")
119 |
120 | # csv data file to be loaded onto 'Neo4J' server (path relative to current working directory)
121 | datafile <- "data.csv"
122 |
123 | # CQL query to write data from datafile to 'Neo4J'
124 | loadcsv_CQL <- "LOAD CSV FROM 'file:///data.csv' etc etc;"
125 |
126 | # path to import directory on remote 'Neo4J' server (should be relative to user home directory on remote server)
127 | impdir <- "./import"
128 |
129 | # import data
130 | neo4jshell::neo4j_import(con = neo_server, source = datafile, import_dir = impdir)
131 |
132 | # write data to 'Neo4J' (assumes cypher-shell is in system PATH variable)
133 | neo4jshell:neo4j_query(con = neo_server, qry = loadcsv_CQL)
134 |
135 | # remove data file as clean-up
136 | neo4jshell::neo4j_rmfiles(con = neo_server, files = datafile, import_dir = impdir)
137 |
138 | In Windows, the ‘cypher-shell’ executable may need to be specified with
139 | the file extension, for example `shell_path = "cypher-shell.bat"`.
140 |
141 | ### Local Development
142 |
143 | If you are working with the ‘Neo4J’ server locally, below will help you
144 | get started.
145 |
146 | First, the code below is relative to user and is using ‘Neo4J 4.0.4
147 | Community’ installed at my user’s root. The directory containing the
148 | ‘cypher-shell’ and ‘neo4j’ executables are in my system’s PATH
149 | environment variables.
150 |
151 | ``` r
152 | ## start the local server
153 | neo4j_start()
154 | #> Directories in use:
155 | #> home: /Users/keithmcnulty/neo4j-community-4.0.4
156 | #> config: /Users/keithmcnulty/neo4j-community-4.0.4/conf
157 | #> logs: /Users/keithmcnulty/neo4j-community-4.0.4/logs
158 | #> plugins: /Users/keithmcnulty/neo4j-community-4.0.4/plugins
159 | #> import: /Users/keithmcnulty/neo4j-community-4.0.4/import
160 | #> data: /Users/keithmcnulty/neo4j-community-4.0.4/data
161 | #> certificates: /Users/keithmcnulty/neo4j-community-4.0.4/certificates
162 | #> run: /Users/keithmcnulty/neo4j-community-4.0.4/run
163 | #> Neo4j is already running (pid 2103).
164 | #> [1] 0
165 |
166 | ## setup connection credentials and import directory location
167 | neo_con <- list(address = "bolt://localhost:7687", uid = "neo4j", pwd = "password")
168 | import_loc <- path.expand("~/neo4j-community-4.0.4/import/")
169 | ```
170 |
171 | First we save `mtcars` to a `.csv` file, and we compress that file. This
172 | package supports a number of delivery formats, but we use a `.zip` file
173 | as an example.
174 |
175 | ``` r
176 | mtcars <- mtcars %>%
177 | tibble::rownames_to_column(var = "model")
178 |
179 | write.csv(mtcars, "mtcars.csv", row.names = FALSE)
180 | zip("mtcars.zip", "mtcars.csv")
181 | ```
182 |
183 | Now we use `neo4j_import()` to place a **copy** of this file within the
184 | import directory you defined in `import_loc` above.
185 |
186 | ``` r
187 | neo4j_import(local = TRUE, graph, source = "mtcars.zip", import_dir = import_loc)
188 | #> Import and unzip successful! Zip file has been removed!
189 | ```
190 |
191 | We now write a CQL query to write some information from `mtcars.csv` to
192 | the graph, and execute that query.
193 |
194 | ``` r
195 | CQL <- "LOAD CSV WITH HEADERS FROM 'file:///mtcars.csv' AS row
196 | WITH row WHERE row.model IS NOT NULL
197 | MERGE (c:Car {name: row.model});"
198 |
199 | neo4j_query(neo_con, CQL)
200 | #> Query succeeded with a zero length response from Neo4J
201 | ```
202 |
203 | Now, let’s remove the `mtcars.csv` file from the import directory of our
204 | local server as cleanup. If you want to use a sub-directory to help
205 | manage your files during an ETL into ‘Neo4J’, you can remove that local
206 | sub-directory when your process has completed using `neo4j_rmdir()`.
207 |
208 | ``` r
209 | ## remove the file
210 | neo4j_rmfiles(local = TRUE, graph, files="mtcars.csv", import_dir = import_loc)
211 | #> Files removed successfully!
212 | ```
213 |
214 | Now let’s run a query to check the data was loaded to the graph.
215 |
216 | ``` r
217 | CQL <- "MATCH (c:Car) RETURN c.name as name LIMIT 5;"
218 |
219 | neo4j_query(neo_con, CQL)
220 | #> name
221 | #> 1 Mazda RX4
222 | #> 2 Mazda RX4 Wag
223 | #> 3 Datsun 710
224 | #> 4 Hornet 4 Drive
225 | #> 5 Hornet Sportabout
226 | ```
227 |
228 | ### Local server administration and control
229 |
230 | - `neo4j_start()` starts a local ‘Neo4J’ instance
231 | - `neo4j_stop()` stops a local ‘Neo4J’ instance
232 | - `neo4j_restart()` restarts a local ‘Neo4J’ instance
233 | - `neo4j_status()` returns the status of a local ‘Neo4J’ instance
234 | - `neo4j_wipe()` wipes an entire graph from a local ‘Neo4J’ instance
235 |
236 | For example:
237 |
238 | ``` r
239 |
240 | # my server was already running, confirm
241 | neo4j_status()
242 | #> Neo4j is running at pid 2103
243 | #> [1] 0
244 |
245 | # stop the server
246 | neo4j_stop()
247 | #> Stopping Neo4j....... stopped
248 | #> [1] 0
249 |
250 | # restart
251 | neo4j_start()
252 | #> Directories in use:
253 | #> home: /Users/keithmcnulty/neo4j-community-4.0.4
254 | #> config: /Users/keithmcnulty/neo4j-community-4.0.4/conf
255 | #> logs: /Users/keithmcnulty/neo4j-community-4.0.4/logs
256 | #> plugins: /Users/keithmcnulty/neo4j-community-4.0.4/plugins
257 | #> import: /Users/keithmcnulty/neo4j-community-4.0.4/import
258 | #> data: /Users/keithmcnulty/neo4j-community-4.0.4/data
259 | #> certificates: /Users/keithmcnulty/neo4j-community-4.0.4/certificates
260 | #> run: /Users/keithmcnulty/neo4j-community-4.0.4/run
261 | #> Starting Neo4j.
262 | #> Started neo4j (pid 12838). It is available at http://localhost:7474/
263 | #> There may be a short delay until the server is ready.
264 | #> See /Users/keithmcnulty/neo4j-community-4.0.4/logs/neo4j.log for current status.
265 | #> [1] 0
266 |
267 | # give it a few seconds to fire up
268 | Sys.sleep(10)
269 |
270 | # query again
271 | neo4j_query(neo_con, qry="MATCH (c:Car) RETURN c.name as name LIMIT 5;")
272 | #> name
273 | #> 1 Mazda RX4
274 | #> 2 Mazda RX4 Wag
275 | #> 3 Datsun 710
276 | #> 4 Hornet 4 Drive
277 | #> 5 Hornet Sportabout
278 | ```
279 |
280 | If you are using an admin account and you are using ‘Neo4J 4+’ you can
281 | check what databases are available by querying the system database.
282 |
283 | ``` r
284 | neo4j_query(neo_con, qry="SHOW DATABASES;", database = "system")
285 | #> name address role requestedStatus currentStatus error default
286 | #> 1 neo4j localhost:7687 standalone online online TRUE
287 | #> 2 system localhost:7687 standalone online online FALSE
288 | ```
289 |
--------------------------------------------------------------------------------
/man/neo4j_import.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/neo4j_import.R
3 | \name{neo4j_import}
4 | \alias{neo4j_import}
5 | \title{Imports a csv or a compressed file to Neo4J import folder.}
6 | \usage{
7 | neo4j_import(
8 | local = FALSE,
9 | con = list(address = NULL, uid = NULL, pwd = NULL),
10 | source = NULL,
11 | import_dir = "import",
12 | unzip_path = "unzip",
13 | gunzip_path = "gunzip",
14 | tar_path = "tar"
15 | )
16 | }
17 | \arguments{
18 | \item{local}{Logical indicating whether import is to a locally hosted or a remotely hosted server.}
19 |
20 | \item{con}{If remotely hosted server, list containing three objects: address, uid, pwd as character strings providing connection to the Neo4J server.
21 | uid and pwd must be for an account on the server with appropriate permissions.}
22 |
23 | \item{source}{Character string of local path to the csv, zip or tar.gz compressed csv file to be imported}
24 |
25 | \item{import_dir}{Character string of full path to the Neo4J import directory}
26 |
27 | \item{unzip_path}{Path to unzip on the local or remote server to be passed to the system command if necessary.}
28 |
29 | \item{gunzip_path}{Path to gunzip on the local or remote server to be passed to the system command following import if necessary.}
30 |
31 | \item{tar_path}{Path to tar on the local or remote server to be passed to the system command following import if necessary.}
32 | }
33 | \value{
34 | System messages confirming success or error. zip or tar files will be removed after import and decompression.
35 | }
36 | \description{
37 | Imports a csv or a compressed file to Neo4J import folder.
38 | }
39 | \examples{
40 | # import zip to local import directory, with zip in the local system PATH variable
41 | write.csv(mtcars, "mtcars.csv")
42 | zip("mtcars.zip", "mtcars.csv")
43 | fs::dir_create("import")
44 | neo4j_import(local = TRUE, source = "mtcars.zip")
45 | fs::file_delete("mtcars.zip")
46 | fs::file_delete("mtcars.csv")
47 | fs::dir_delete("import")
48 | }
49 |
--------------------------------------------------------------------------------
/man/neo4j_query.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/neo4j_query.R
3 | \name{neo4j_query}
4 | \alias{neo4j_query}
5 | \title{Execute a query string in Neo4J using cypher-shell and capture output}
6 | \usage{
7 | neo4j_query(
8 | con = list(address = NULL, uid = NULL, pwd = NULL),
9 | qry = NULL,
10 | shell_path = "cypher-shell",
11 | database = NULL,
12 | encryption = c("default", "true", "false")
13 | )
14 | }
15 | \arguments{
16 | \item{con}{List containing three objects: bolt address, uid, pwd as character strings providing connection to the Neo4J server}
17 |
18 | \item{qry}{Character string of the query or queries to be sent to Neo4J. Read queries should be single queries.}
19 |
20 | \item{shell_path}{If cypher-shell is not in the PATH system variable, the full local path to cypher-shell executable.}
21 |
22 | \item{database}{The name of the database if other than the default database. (For multi-tenancy installations).}
23 |
24 | \item{encryption}{Passes encryption argument to cypher-shell if necessary. Older versions of cypher-shell may require 'true' or 'false' to be passed.}
25 | }
26 | \value{
27 | A dataframe of results if the read query is successful. A text string if an error is encountered.
28 | Write queries will return a zero length response if successful.
29 | If multiple read queries were submitted, only the results of the final query will be returned.
30 | }
31 | \description{
32 | Execute a query string in Neo4J using cypher-shell and capture output
33 | }
34 | \examples{
35 | # if neo4j exists, start the local server, give it a moment to fire up, and run a query
36 | if (nzchar(Sys.which("neo4j"))) {
37 | neo4j_start()
38 | Sys.sleep(2)
39 | graph <- list(address = "bolt://localhost:7687", uid = "neo4j", pwd = "password")
40 | neo4j_query(con = graph, qry = "MATCH (n) RETURN (n)")
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/man/neo4j_restart.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/neo4j_restart.R
3 | \name{neo4j_restart}
4 | \alias{neo4j_restart}
5 | \title{Restart a local Neo4J database}
6 | \usage{
7 | neo4j_restart(neo4j_path = "neo4j")
8 | }
9 | \arguments{
10 | \item{neo4j_path}{Path to the Neo4J executable (usually in the bin directory of the Neo4J installation)}
11 | }
12 | \value{
13 | System messages
14 | }
15 | \description{
16 | Restart a local Neo4J database
17 | }
18 | \examples{
19 | # if neo4j exists, restart local graph with neo4j executable in the system PATH variable
20 | if (nzchar(Sys.which("neo4j"))) {
21 | neo4j_restart()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/man/neo4j_rmdir.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/neo4j_rmdir.R
3 | \name{neo4j_rmdir}
4 | \alias{neo4j_rmdir}
5 | \title{Remove subdirectory and all its contents from the Neo4J import directory}
6 | \usage{
7 | neo4j_rmdir(
8 | local = FALSE,
9 | con = list(address = NULL, uid = NULL, pwd = NULL),
10 | dir = NULL,
11 | import_dir = "import"
12 | )
13 | }
14 | \arguments{
15 | \item{local}{Logical indicating whether import is to a locally hosted or remotely hosted server.}
16 |
17 | \item{con}{If remotely hosted server, list containing three objects: address, uid, pwd as character strings providing connection to the Neo4J server.
18 | uid and pwd must be for an account on the server with appropriate permissions.}
19 |
20 | \item{dir}{Character string of the Neo4J import subdirectory name to be deleted.}
21 |
22 | \item{import_dir}{Character string of path to the Neo4J import directory.}
23 | }
24 | \value{
25 | A success message if successful. A error message otherwise.
26 | }
27 | \description{
28 | Remove subdirectory and all its contents from the Neo4J import directory
29 | }
30 | \examples{
31 | # remove a subdirectory and all its contents from the local import directory
32 | fs::dir_create("import/data")
33 | fs::file_create("import/data/data.csv")
34 | neo4j_rmdir(local = TRUE, dir = "data", import_dir = "import")
35 | fs::dir_delete("import")
36 | }
37 |
--------------------------------------------------------------------------------
/man/neo4j_rmfiles.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/neo4j_rmfiles.R
3 | \name{neo4j_rmfiles}
4 | \alias{neo4j_rmfiles}
5 | \title{Remove files from the Neo4J import directory}
6 | \usage{
7 | neo4j_rmfiles(
8 | local = FALSE,
9 | con = list(address = NULL, uid = NULL, pwd = NULL),
10 | files = NULL,
11 | import_dir = "import"
12 | )
13 | }
14 | \arguments{
15 | \item{local}{Logical indicating whether import is to a locally hosted or remotely hosted server.}
16 |
17 | \item{con}{If remotely hosted server, list containing three objects: address, uid, pwd as character strings providing connection to the Neo4J server.
18 | uid and pwd must be for an account on the server with appropriate permissions.}
19 |
20 | \item{files}{Character vector of file names to be removed.}
21 |
22 | \item{import_dir}{Character string of path to the Neo4J import directory.}
23 | }
24 | \value{
25 | A success message if successful. An error message otherwise.
26 | }
27 | \description{
28 | Remove files from the Neo4J import directory
29 | }
30 | \examples{
31 | # remove file from local import directory
32 | fs::dir_create("import")
33 | fs::file_create("import/data.csv")
34 | neo4j_rmfiles(local = TRUE, files = "data.csv", import_dir = "import")
35 | fs::dir_delete("import")
36 | }
37 |
--------------------------------------------------------------------------------
/man/neo4j_start.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/neo4j_start.R
3 | \name{neo4j_start}
4 | \alias{neo4j_start}
5 | \title{Start a local Neo4J database}
6 | \usage{
7 | neo4j_start(neo4j_path = "neo4j")
8 | }
9 | \arguments{
10 | \item{neo4j_path}{Path to the Neo4J executable (usually in the bin directory of the Neo4J installation)}
11 | }
12 | \value{
13 | System messages
14 | }
15 | \description{
16 | Start a local Neo4J database
17 | }
18 | \examples{
19 | # if neo4j exists, start local graph on with neo4j executable in the system PATH variable
20 | if (nzchar(Sys.which("neo4j"))) {
21 | neo4j_start()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/man/neo4j_status.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/neo4j_status.R
3 | \name{neo4j_status}
4 | \alias{neo4j_status}
5 | \title{Check status of a local Neo4J database}
6 | \usage{
7 | neo4j_status(neo4j_path = "neo4j")
8 | }
9 | \arguments{
10 | \item{neo4j_path}{Path to the Neo4J executable (usually in the bin directory of the Neo4J installation)}
11 | }
12 | \value{
13 | System messages
14 | }
15 | \description{
16 | Check status of a local Neo4J database
17 | }
18 | \examples{
19 | # if neo4j exists, check status local graph with neo4j executable in the system PATH variable
20 | if (nzchar(Sys.which("neo4j"))) {
21 | neo4j_status()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/man/neo4j_stop.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/neo4j_stop.R
3 | \name{neo4j_stop}
4 | \alias{neo4j_stop}
5 | \title{Stop a local Neo4J database}
6 | \usage{
7 | neo4j_stop(neo4j_path = "neo4j")
8 | }
9 | \arguments{
10 | \item{neo4j_path}{Path to the Neo4J executable (usually in the bin directory of the Neo4J installation)}
11 | }
12 | \value{
13 | System messages
14 | }
15 | \description{
16 | Stop a local Neo4J database
17 | }
18 | \examples{
19 | # if neo4j exists, stop local graph with neo4j executable in the system PATH variable
20 | if (nzchar(Sys.which("neo4j"))) {
21 | neo4j_stop()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/man/neo4j_wipe.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/neo4j_wipe.R
3 | \name{neo4j_wipe}
4 | \alias{neo4j_wipe}
5 | \title{Wipe a complete local graph database in Neo4J}
6 | \usage{
7 | neo4j_wipe(database = NULL, data_path = NULL)
8 | }
9 | \arguments{
10 | \item{database}{Name of local graph database directory to wipe.}
11 |
12 | \item{data_path}{Path to the local Neo4J data directory}
13 | }
14 | \value{
15 | Success or error message
16 | }
17 | \description{
18 | Wipe a complete local graph database in Neo4J
19 | }
20 | \examples{
21 | # wipe database directory
22 | fs::dir_create("data/databases/foo")
23 | neo4j_wipe(database = "foo", data_path = "data")
24 | fs::dir_delete("data")
25 | }
26 |
--------------------------------------------------------------------------------
/neo4jshell.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
15 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageUseDevtools: Yes
20 | PackageInstallArgs: --no-multiarch --with-keep.source
21 |
--------------------------------------------------------------------------------
/neo4jshell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/keithmcnulty/neo4jshell/08ebf6446554bacdce003a8a11057d1ff55f9a3f/neo4jshell.png
--------------------------------------------------------------------------------
/vignettes/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 | *.R
3 |
--------------------------------------------------------------------------------
/vignettes/admin.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Server Admin"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{Server Admin}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | ```{r, include = FALSE}
11 | knitr::opts_chunk$set(
12 | collapse = TRUE,
13 | comment = "#>"
14 | )
15 | ```
16 |
17 | This package contains functions for administering a local Neo4J server.
18 |
19 | ### Start, stop, restart or check the status of a local Neo4J server
20 |
21 | `neo4J_start()`, `neo4j_stop()`, `neo4j_restart()` and `neo4j_status()` perform a stop, start, restart or reports the current status of a local Neo4J instance. These functions take a single argument `neo4j_path` which should be a path to the local `neo4j` executable. Use `path.expand()` where necessary.
22 |
23 | ```{r example, eval = FALSE}
24 | library(neo4jshell)
25 |
26 | neo_path <- path.expand("~/neo4j-community-4.0.4/bin/neo4j")
27 | neo4j_status(neo_path)
28 | ```
29 |
30 | All these functions output system messages.
31 |
32 | ### Wipe a specified graph from a local Neo4J server
33 |
34 | `neo4j_wipe()` completely removes a graph from the local Neo4J server. It takes two arguments:
35 |
36 | * `database` is the name of the graph database file to be wiped.
37 | * `data_path` is the path to the data directory of the local Neo4J server. Use `path.expand()` if necessary.
38 |
39 | ``` {r example2, eval = FALSE}
40 | graphfile <- "graph.db"
41 | my_data_path <- path.expand("~/neo4j-community-4.0.4/data")
42 | neo4j_wipe(graphfile, my_data_path)
43 |
44 | ```
45 |
46 | This function will output a success or an error message.
47 |
48 | ### Note for Windows users
49 |
50 | Paths to executable files that are provided as arguments to functions may need to be provided with appropriate extensions (eg `neo4j.bat`).
51 |
--------------------------------------------------------------------------------
/vignettes/files.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Importing and managing data"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{Importing and managing data}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | ```{r, include = FALSE}
11 | knitr::opts_chunk$set(
12 | collapse = TRUE,
13 | comment = "#>"
14 | )
15 | ```
16 |
17 | The package provides three functions for importing and managing data with Neo4J.
18 |
19 | ### Importing data
20 |
21 | The function `neo4j_import()` copies a `.csv`, `.zip` or `.tar.gz` file into the specified import directory on the Neo4J server. If the file is compressed, it will automatically decompress the file into the import directory and remove the compressed file afterwards.
22 |
23 | `neo4j_import()` takes the following arguments:
24 |
25 | * `local` should be a logical value indicating if the Neo4J server is locally or remotely hosted.
26 | * `con` should be a list containing three elements: `address`, which should be address of the Neo4J hosting server, and `uid` and `pwd` as login credentials. The bolt address used for querying can be used only if the hosting server uses the same address. Only used if `local = FALSE`.
27 | * `source` is the local path to the file to be imported. Use `path.expand()` if necessary.
28 | * `import_dir` is the local or remote path to the Neo4J import directory. Use `path.expand()` if necessary.
29 | * `unzip_path` is the path to the `unzip` executable on the local or remote server. Only used if a `zip` is imported.
30 | * `gunzip_path` is the path to the `gunzip` executable on the local or remote server. Only used if a `.tar.gz` is imported.
31 | * `tar_path` is the path to the `tar` executable on the local or remote server. Only used if a `.tar.gz` is imported.
32 |
33 | Example, importing a file named `data.csv` to a locally hosted Neo4J server:
34 |
35 | ``` {r, eval = FALSE}
36 | library(neo4jshell)
37 |
38 | file <- "data.csv" # assumes file is present in current working directory
39 | impdir <- path.expand("~/neo4j-community-4.0.4/import")
40 | neo4j_import(local = TRUE, source = file, import_dir = impdir)
41 |
42 | ```
43 |
44 | The function returns either a success message or an error message.
45 |
46 | ### Removing files from the import directory
47 |
48 | The function `neo4j_rmfiles()` allows the removal of files from the specified Neo4J import directory, which can be useful for cleaning up following import.
49 |
50 | `neo4j_rmfiles()` takes the following arguments:
51 |
52 | * `local` should be a logical value indicating if the Neo4J server is locally or remotely hosted.
53 | * `con` should be a list containing three elements: `address`, which should be the address of the Neo4J hosting server, and `uid` and `pwd` as login credentials. The bolt address used for querying can be used only if the hosting server uses the same address. Only used if `local = FALSE`.
54 | * `source` is a character vector listing the names of the files to be removed from the import directory.
55 | * `import_dir` is the local or remote path to the Neo4J import directory. Use `path.expand()` if necessary.
56 |
57 | Example, removing a file named `data.csv` from a locally hosted Neo4J server:
58 |
59 | ``` {r, eval = FALSE}
60 | library(neo4jshell)
61 |
62 | file <- "data.csv"
63 | impdir <- path.expand("~/neo4j-community-3.5.8/import")
64 | neo4j_rmfiles(local = TRUE, files = file, import_dir = impdir)
65 |
66 | ```
67 |
68 | The function returns either a success message or an error message.
69 |
70 | ### Removing subdirectories from the import directory
71 |
72 | The function `neo4j_rmdir()` allows the removal of an entire sub-directory and all its contents from the specified Neo4J import directory, which can be useful for cleaning up following import.
73 |
74 | `neo4j_rmdir()` takes the following arguments:
75 |
76 | * `local` should be a logical value indicating if the Neo4J server is locally or remotely hosted.
77 | * `con` should be a list containing three elements: `address`, which should be the address of the Neo4J hosting server, and `uid` and `pwd` as login credentials. The bolt address used for querying can be used only if the hosting server uses the same address. Only used if `local = FALSE`.
78 | * `dir` is the name of the subdirectory of the import directory to be removed.
79 | * `import_dir` is the local or remote path to the Neo4J import directory. Use `path.expand()` if necessary.
80 |
81 | Example, removing a directory called `data` from a locally hosted Neo4J server:
82 |
83 | ``` {r, eval = FALSE}
84 | library(neo4jshell)
85 |
86 | datadir <- "data"
87 | impdir <- path.expand("~/neo4j-community-4.0.4/import")
88 | neo4j_rmdir(local = TRUE, dir = datadir, import_dir = impdir)
89 |
90 | ```
91 |
92 | The function returns either a success message or an error message.
93 |
94 | ### Smooth ETL in Neo4J
95 |
96 | These functions can be used in combination with `neo4j_query()` to set up smooth ETL on a Neo4J server, by executing in the following order:
97 |
98 | 1. `neo4j_import()` to transfer a data file into the import directory or into a subdirectory (if the compressed file involves a subdirectory).
99 | 2. `neo4j_query()` to execute a load query referencing the imported file.
100 | 3. `neo4j_rmfiles()` or `neo4j_rmdir()` to remove the imported files following a successful load query.
101 |
102 | ### Note for Windows users
103 |
104 | Paths to executable files that are provided as arguments to functions may need to be provided with appropriate extensions (eg `cypher-shell.bat`).
105 |
106 |
--------------------------------------------------------------------------------
/vignettes/querying.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Querying Neo4J"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{Querying Neo4J}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | ```{r, include = FALSE}
11 | knitr::opts_chunk$set(
12 | collapse = TRUE,
13 | comment = "#>"
14 | )
15 | ```
16 |
17 | The function `neo4j_query()` can be used to send a query to a local or remote Neo4J server. This function uses `cypher-shell` to send the query to Neo4J, and so the `cypher-shell` executable needs to be installed and available locally. See the `README` file for further information on configuration of the `cypher-shell` executable.
18 |
19 | `neo4j_query()` takes the following arguments:
20 |
21 | * `con` should be a list containing three elements: `address`, which should be the bolt address of the Neo4J server, and `uid` and `pwd` as login credentials
22 | * `qry` should be a character string representing the query to be sent to Neo4J
23 | * `shell_path` should be the full path to the `cypher-shell` executable. The default value assumes that `cypher-shell` is already in the system path. Use `path.expand()` if necessary.
24 | * `database` specifies the database to be queried if not the default database. (For multitenancy Neo4J installations).
25 | * `encryption` is the encryption option passed to `cypher-shell`. This may be required as explicitly `'true'` or `'false'` for older installations.
26 |
27 | Example, assuming a local Neo4J instance running the movies graph:
28 |
29 | ```{r example, eval = FALSE}
30 | library(neo4jshell)
31 |
32 | neo4j_local <- list(address = "bolt://localhost", uid = "neo4j", pwd = "password")
33 | CQL <- 'MATCH (p1:Person {name: "Kevin Bacon"})-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(p2:Person)
34 | RETURN p2.name AS Name, m.title AS Title'
35 | cypher_path <- path.expand("~/neo4j-community-4.0.4/bin/cypher-shell")
36 | neo4j_query(con = neo4j_local, qry = CQL, shell_path = cypher_path)
37 |
38 | ```
39 |
40 | This query should return this dataframe:
41 |
42 | ``` {r example-output, echo = FALSE}
43 |
44 | data.frame(Name = c("Ron Howard", "Rob Reiner", "Ron Howard"),
45 | Title = c("Frost/Nixon", "A Few Good Men", "Apollo 13"))
46 |
47 | ```
48 |
49 | `neo4j_query()` accepts multiple query statements separated by `;`. The function returns one of the following:
50 |
51 | * A dataframe of results if the query is a read query. If there were multiple statements, only the results of the final statement will display.
52 | * A message indicating successful execution if the query is a write query.
53 | * An error message if an error occurred. If there were multiple statements, the response for all statements will be displayed.
54 |
55 | ### Note for Windows users
56 |
57 | Paths to executable files that are provided as arguments to functions may need to be provided with appropriate extensions (eg `cypher-shell.bat`).
58 |
--------------------------------------------------------------------------------