We've encoded a property graph into javascript objects in a form that has a natural correspondence to neo4j's cypher query language.
See Transform to Nodes and Rels for the encoding.
See Match Nodes and Rels for our first queries.
We will use the type vocabulary from Mock Graph Data for these examples. This rolls up into a schema with 4 node types and 6 rel types.
strict digraph { rankdir=TB node [shape=box style=filled fillcolor=palegreen] Employee -> Employee [label=Manager] Project -> Employee [label=Manager] Service -> Project [label=Owner] Service -> Employee [label=Team] Service -> Service [label=Flow] Service -> Statistic [label=Traffic]}
We find all Employees or some subset of these.
// All Employees // match (n:Employee) let n = nodes .filter(node => node.type == 'Employee')
// An Employee named A. J. Flores // match (n:Employee {name:'A. J. Flores'}) let n = nodes .filter(node => node.type == 'Employee' && node.props.name == 'A. J. Flores')
// All Employees named Flores // match (n:Employee) where n.name contains 'Flores' let n = nodes .filter(node => node.type == 'Employee' && node.props.name.includes('Flores'))
We further subset Employees by their relations.
// All Employees n that are managers. // match (n) <-[:Manager]- () let n = n .filter(node => node.in .find(rid => rels[rid].type == 'Manager')
// All Employees n that are managers of a Project. // match (n) <-[:Manager]- (:Project) let n = n .filter(node => node.in .find(rid => rels[rid].type == 'Manager' && nodes[rels[rid].from].type == 'Project')
// All Employees n that are something of a Project. // match (n) <-- (:Project) let n = n .filter(node => node.in .find(rid => nodes[rels[rid].from].type == 'Project')
// All Employees n that are something of a Project. // match (n) -- (:Project) let n = n .filter(node => [...node.in, ...node.out] .find(rid => nodes[rels[rid].from].type == 'Project' || nodes[rels[rid].to].type == 'Project')