Context :
A system where a number of points of interest (pois) are related to each other in multiple hierarchies. A can be B's parent in one hierarchy, while in another hierarchy A can be B's child (or even a further descendant). For this reason the Neo4j graph contains hierarchies and parentchildrelations as seperate nodes, instead of linking pois with [isChildOf] relations.
the graph to illustrate this can be generated using this cypher script. I'm using Neo4j 2.0.0-M06.
I've included some labels for readability, but I don't want to rely on them for the queries.
create (_1 {`name`:"Class"})
create (_4:Class {`name`:"Poi"})
create (_5:Class {`name`:"PoiType"})
create (_9:Class {`name`:"Hierarchy"})
create (_10:Class {`name`:"ParentChildRelation"})
create _4-[:`isA`]->_1
create _5-[:`isA`]->_1
create _9-[:`isA`]->_1
create _10-[:`isA`]->_1
create (_26:PoiType {`poitypeid`:"2", `name`:"City"})
create (_27:PoiType {`poitypeid`:"3", `name`:"Province "})
create (_28:PoiType {`poitypeid`:"4", `name`:"Country"})
create (_29:Poi {`poiid`:"72882",`name`:"Netherlands"})
create (_30:Poi {`poiid`:"126",`name`:"Gelderland"})
create (_31:Poi {`poiid`:"52662",`name`:"Wageningen"})
create (_32:Poi {`poiid`:"8839",`name`:"Ede"})
create _26-[:`isA`]->_5
create _27-[:`isA`]->_5
create _28-[:`isA`]->_5
create _29-[:`isA`]->_4
create _30-[:`isA`]->_4
create _31-[:`isA`]->_4
create _32-[:`isA`]->_4
create _29-[:`isOfType`]->_28
create _30-[:`isOfType`]->_27
create _31-[:`isOfType`]->_26
create _32-[:`isOfType`]->_26
create (_33:Hierarchy {`treeid`:"1",`name`:"GeoAdmin"})
create _33-[:`isA`]->_9
create _33-[:`isOfType`]->_4
create (_34:ParentChildRelation {`pcrid`:"1"})
create _34-[:`isA`]->_10
create _34-[:`belongsTo`]->_33
create _34-[:`relationParent`]->_29
create _34-[:`relationChild`]->_30
create (_35:ParentChildRelation {`pcrid`:"2"})
create _35-[:`isA`]->_10
create _35-[:`belongsTo`]->_33
create _35-[:`relationParent`]->_30
create _35-[:`relationChild`]->_31
create (_36:ParentChildRelation {`pcrid`:"3"})
create _36-[:`isA`]->_10
create _36-[:`belongsTo`]->_33
create _36-[:`relationParent`]->_30
create _36-[:`relationChild`]->_32
create (_37:Hierarchy {`treeid`:"2",`name`:"SomePoiHierarchy"})
create _37-[:`isA`]->_9
create _37-[:`isOfType`]->_4
create (_38:ParentChildRelation {`pcrid`:"4"})
create _38-[:`isA`]->_10
create _38-[:`belongsTo`]->_37
create _38-[:`relationParent`]->_29
create _38-[:`relationChild`]->_32
;
To have an overview of the hierarchical relations, queries like this work fine:
MATCH ptp<-[r4:isOfType]-p<-[r1:relationParent]-pcr-[r2:relationChild]->c-[r5:isOfType]->ptc,pcr-[r3:belongsTo]->h
RETURN ptp.name,p.name,ptc.name,c.name,h.name
resulting in this:
ptp.name p.name ptc.name c.name h.name
Country Netherlands City Ede SomePoiHierarchy
Country Netherlands Province Gelderland GeoAdmin
Province Gelderland City Ede GeoAdmin
Province Gelderland City Wageningen GeoAdmin
As illustration, this is one of the paths that exit in the graph
Nederland <- [relationParent] – pcr(1) – [relationChild] -> Gelderland <- [relationParent] – pcr(2) – [relationChild] -> Wageningen
Question :
When I want to get all nodes of a given type in a branch in the hierarchy, I have an undefined number of constructs like
<- [relationParent] – pcr – [relationChild] ->
in the path.
When using a direct [isChildOf] relation between nodes, I would use something like this
start n=node(84)
match n<-[r1:IsChildOf*]-m-[r2:IsOfType]->pt
where pt.name="City"
return n,n.name,m,m.name,pt.name
But now I need some syntax that allows me to repeat the entire construct including the relations through the parentchildrelation node.
Who knows how to do this ?