R/graphninja.R

Defines functions graph_heroku_graphene create_node get_or_create_node create_rel key_val list_to_key_val get_nodes

#' Start a graph in Graphene from Heroku Rails App
#' 
#' Rails is a web-framework based on the ruby language.  Heroku is a cloud platform as a service
#' that supports rails.  GrapheneDB operates hosted, production-ready Neo4j graph databases.  
#' Heroku has a GrapheneDB add-on, such that one can host a rails app with a Neo4j db on Heroku. 
#' This uses the \code{heroku config:get GRAPHENEDB_URL} command to grab credentials from Heroku
#' parse them, then start a graph.  For more info see: \url{https://devcenter.heroku.com/articles/graphenedb}
#' @param remote the name of the remote repository. The default remote is used otherwise.
#' @return a graph object connected to the cloud-based database.  
graph_heroku_graphene <- function(remote = NULL){
  if(is.null(remote)){
    environment_var <- system("cd ../; heroku config:get GRAPHENEDB_URL", TRUE)
  }else{
    environment_var <- system(paste("cd ../; heroku config:get GRAPHENEDB_URL --remote", remote), TRUE)
  }
  username <- str_split(environment_var, ":")[[1]][2] %>% str_replace_all("/", "")
  password <- str_split(environment_var, ":")[[1]][3] %>% 
    str_split("@") %>% 
    unlist %>%
    `[`(1)
  url <- str_split(environment_var, ":")[[1]][3:4] %>% 
    str_c(collapse = ":") %>%
    str_split("@") %>% 
    unlist %>%
    `[`(2) %>%
    str_c("/db/data/")
  startGraph(url, username, password)
}

#' Create node from a list of node properties
#' 
#' Takes a list of node properties and creates a node using createNode from RNeo4j. Useful for
#' when you want to create a bunch of nodes in bulk.  The list must have names corresponding to the 
#' desired property names.  The list value corresponding to the label of the node must be named '.label'.
#' @param arg_list list of property arguments
#' @param the graph object corresponding the the Neo4j db
#' @return a RNeo4j node object
#' @example args <- list(.label = "Person", name = "Bob", age = 24)
#' create_node(args, g)
create_node <- function(arg_list, g){
  args <- c(list(graph = g), arg_list)
  do.call(createNode, args)
}
#' @rdname create_node
get_or_create_node <- function(arg_list, g){
  args <- c(list(graph = g), arg_list)
  do.call(getOrCreateNode, args)
}

#' Create relationship from a list containing nodes and relationship properties
#' 
#' Takes a list of nodes and relationship properties and creates a relationship. Useful for
#' when you want to create a bunch of relationships in bulk.  
#' @param arg_list list with the following named elements;\itemize{
#'  \item{".fromNode"}{node object},
#'  \item{".relType"}{relationship type, all caps, underscore for spaces},
#'  \item{".toNode"}{node object}
#'  } Additionally, other property names and values for the relationship can be included as well.
#' @return a RNeo4j relationship object
#' @seealso create_node
#' @example 
#' g = startGraph("http://localhost:7474/db/data/")
#' clear(g)
#' alice_node <- list(.label = "Person", name = "Alice") %>% create_node(g)
#' bob_node <- list(.label = "Person", name = "Bob") %>% create_node(g)
#' alice_knows_bob <- list(.fromNode = bob, .relType = "KNOWS", .toNode = alice, since = 2000, through = WORK) %>%
#'    create_rel
create_rel <- function(arg_list){
  do.call(createRel, arg_list)
}

#' Convert a list to a list of key value pairs
#' 
#' Create a list of key value pairs from a single key and multiple values.  
#' 
#' Given a single "key" character and multiple "values", this builds a list of key-value lists.
#' @param key a single character object
#' @param values a parameter vector
#' @return a list of lists where each sublist has two elements named key and value  
key_val <- function(key, values){
  lapply(values, function(item){
    list(key = key, value = item)
  })
}

#' Convert a named list to a list of key-value lists
#' 
#' This is like the data frame one would get using reshape::melt.list on a list, 
#' except each row in the data frame is replaced by a one element list where the first element of the row 
#' is the name, and the second element of the row is the value of the list element.
list_to_key_val <- function(list_item){
  lapply(names(list_item), function(item){
    key_val(item, list_item[[item]])
  }) %>%
    unlist(recursive = FALSE)
}

#' Pull node objects from a list by matching a node property
#' 
#' Given a list of objects of the RNeo4j 'node' class, subset the list to all objects that have
#' a specific value for a specific property. 
#' @param node_list a list of nodes
#' @param property the name of the property
#' @param value the desired value of the property
#' @return a list of the subset of nodes that have the correct value for the property
get_nodes <- function(node_list, property, value){
  indx <- lapply(node_list, function(node) node[[property]] == value) %>% unlist
  node_list[indx]
}
robertness/graphninja documentation built on May 27, 2019, 11:40 a.m.