cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

How can I more effectively return same-labeled nodes in a single property without using UNION?

MATCH (t:Timetable)<-[:BASED_ON]-(n)-[:REL_1]->()
WHERE id(t)=1234
optional MATCH (n)<-[:LIGHT_SETTINGS]-(sc:Scheduler)-[:REL_2]->(e:Equipment)-[:TYPE_OF]->(et:EquipmentType)
OPTIONAL match (e)-[:PARENT*]->(si:Site) 
RETURN n.`_entity` as referenceType, ID(e) as resourceId, ID(et) as equipmentType,  ID(si) as siteId, ID(n)
UNION
MATCH (t:Timetable)<-[:BASED_ON]-(n)-[:CONTROLS]->()
WHERE id(t)=1234
OPTIONAL MATCH (n)-[:CONTROLS]->(e:Equipment)-[:TYPE_OF]->(et:EquipmentType)
OPTIONAL MATCH (e)-[:PARENT*]->(si:Site) 
RETURN n.`_entity` as referenceType, ID(e) as resourceId, ID(et) as equipmentType,  ID(si) as siteId, ID(n)

Im trying to return a property that is accessed by 2 different paths, depending on the Label, in this case, the Label of (n). As is, this is quite messy and shoud be able to be optimized.
This is the first solution i was able to get that returns (e) and (et) found on 2 possible paths. Thanks for reading!

3 REPLIES 3

Hey there,

Have you considered mixing OR conditions on your edges with variable path lengths?
Something like this may work depending on your data model:

MATCH (t:Timetable)<-[:BASED_ON]-(n)-[:REL_1]->()
WHERE id(t)=1234
optional MATCH (n)<-[:LIGHT_SETTINGS|:REL_2|CONTROLS*1..2]->(e:Equipment)-[:TYPE_OF]->(et:EquipmentType)
OPTIONAL match (e)-[:PARENT*]->(si:Site) 
RETURN n.`_entity` as referenceType, ID(e) as resourceId, ID(et) as equipmentType,  ID(si) as siteId, ID(n)

Benoit_d
Graph Buddy

Hi,

as far as I understand, you are looking for the equipment. "n" (unlabeled) is just part of the path to it.
You probably want to reduce the complexity not especially the UNION

MATCH (t:Timetable)<-[:BASED_ON]-(n)-[:REL_1]->(), (n)<-[:LIGHT_SETTINGS]-(sc:Scheduler)-[:REL_2]->(e:Equipment)
WHERE id(t)=1234
UNION
MATCH (t:Timetable)<-[:BASED_ON]-(n)-[:CONTROLS]->(), (n)-[:CONTROLS]->(e:Equipment)
WHERE id(t)=1234
with distinct n, e 
OPTIONAL MATCH (e)-[:TYPE_OF]->(et:EquipmentType)
OPTIONAL MATCH (e)-[:PARENT*]->(si:Site) 
RETURN n.`_entity` as referenceType, ID(e) as resourceId, ID(et) as equipmentType,  ID(si) as siteId, ID(n)

(not tested)

MATCH (t:Timetable)<-[:BASED_ON]-(n)-[:CONTROL_BOARD|:CONTROLS]->() 
WHERE id(t)={0} 
OPTIONAL MATCH (n)-[:CONTROLS]->(r1:Equipment)-[:TYPE_OF]->(et1:EquipmentType) 
OPTIONAL MATCH (n)<-[:LIGHT_SETTINGS]-(sc:Scheduler)-[:CONTROLS]->(r2:Equipment)-[:TYPE_OF]->(et2:EquipmentType) 
WITH COALESCE(r1,r2) AS r, 
COALESCE(et1,et2) AS et,
n,
OPTIONAL MATCH (r)-[:PARENT*]->(si:Site) 
RETURN  n.`_entity` as referenceType,  ID(r) as resourceId, ID(et) as equipmentTypeId, ID(si) as siteId

From another forum I got a tip to use COALESCE(), which makes things a bit cleaner. But as im adding properties to be returned, seems like the query is too complex.