As an alternative to the officially supported drivers (.NET, Go, Java, JavaScript, and Python), you’ve been able to query a Neo4j server via an HTTP API. However, this has been limited to self-managed instances and wasn’t available on the Neo4j Aura cloud service.
In September 2024, Neo4j released a new production-grade Query API that extends the capability for HTTP API-based Cypher interactions across all Aura tiers and cloud providers.
There are community-supported drivers for connecting R to Neo4j (neo2R, neo4r, and neo4jshell), but these use the original Neo4j HTTP API, along with some R packages that are no longer recommended (e.g., httr).
This article will demonstrate how the httr2 package and Neo4j Query API can be combined to make a simple Cypher query and return a dataframe.
Query API URL
The URL contains two mandatory components that define the Neo4j server hostname and database name (the default name is ‘neo4j’):
https://NEO4J_SERVER_HOSTNAME/db/NEO4J_DATABASE_NAME/query/v2
HTTP Request in R
Using httr2, the HTTP request is formed from the Query API URL, authentication credentials (NEO4J_USERNAME and NEO4J_PASSWORD), and the Cypher query statement (CYPHER_QUERY). Please substitute with appropriate values.
library(tidyverse)
library(httr2)
req <- request("https://NEO4J_SERVER_HOSTNAME/db/NEO4J_DATABASE_NAME/query/v2") |>
req_auth_basic("NEO4J_USERNAME", "NEO4J_PASSWORD") |>
req_headers("Accept" = "application/json") |>
req_body_json(list("statement" = "CYPHER_QUERY"))
Perform the query and capture the response:
resp <- req |> req_perform()
resp
Transform JSON response to dataframe:
json <- resp |> resp_body_json(simplifyVector = TRUE)
names <- json |> pluck("data", 1)
df <- json |> pluck("data", 2) |> data.frame()
colnames(df) = c(names)
Query Function
These code snippets can be combined to yield a function to perform the Cypher query and return the result as a dataframe:
neo4j_query <- function(cypher, db_settings){
# Create https request
req <- request(paste0("https://", db_settings['server'], "/db/", db_settings['database'], "/query/v2")) |>
req_auth_basic(db_settings['username'], db_settings['password']) |>
req_headers("Accept" = "application/json") |>
req_body_json(list("statement" = cypher))
# Perform request
resp <- req |> req_perform()
# Extract response and create dataframe
json <- resp |> resp_body_json(simplifyVector = TRUE)
names <- json |> pluck("data", 1)
df <- json |> pluck("data", 2) |> data.frame()
# Rename columns
colnames(df) = c(names)
df
}
We can then use a vector for the Neo4j settings, pass the Cypher query along the chain, and return the dataframe:
neo4j_settings = c(server = "NEO4J_SERVER_HOSTNAME", username="NEO4J_USER", password="NEO4J_PASSWORD", database="NEO4J_DATABASE_NAME")
cypher = "CYPHER_QUERY"
df <- cypher |> neo4j_query(neo4j_settings)
Warning
This simple example should be used with caution since we’re missing any form of error handling in the connection and/or the Cypher query response. Also, all the data types returned via JSON will be of character (chr) type and may require appropriate transformation.
Example
We connect to a Neo4j demo server and run a query against the movie recommendations database. The query identifies users who rated the film Crimson Tide and the films that those same users also rated (Users who got this item also got that other item).
neo4j_settings = c(server="demo.neo4jlabs.com:7473", username="recommendations", password="recommendations", database="recommendations")
cypher = "MATCH (m:Movie {title: 'Crimson Tide'})<-[:RATED]-(u:User)-[:RATED]->(rec:Movie)
WITH rec, COUNT(*) AS usersWhoAlsoWatched
ORDER BY usersWhoAlsoWatched DESC LIMIT 10
RETURN rec.title AS recommendation, usersWhoAlsoWatched"
df <- cypher |> neo4j_query(neo4j_settings)
Summary
This scratches the surface of what you can do with the Query API, and there are many other features:
- Parameterized queries
- Explicit transactions
- JSON with type information
- User impersonation
- Token-based authentication
Take a look at the Query API documentation. You can also learn about moving to the Query API.
Using Neo4j Query API With R on Aura was originally published in Neo4j Developer Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.