'Neo4j subgraph of different nodes with different labels and relationship if any

I recently started using neo4j and its query language "cypher" for working with building/metering data.

My current graph database consists of different nodes (with different labels such as: point,meter,elec,equip ..etc. just to name a few), and each having different properties (not relevant in this context).

What I would like to do, is to get a sub-graph of different nodes which have different labels. For instance I would like to get all the nodes labeled as "point" as well as the ones labeled "equip" and the ones labeled as "meter". To do so I tried the following query:

MATCH (p:point)
MATCH (e:equip)
MATCH (m:meter)
RETURN p, e, m

However that does not work since: This query builds a cartesian product between disconnected patterns.

I am trying to get these so that, if a node labeled "point" is connected to either an "equip" or "meter" node, I would get the relationship. If nothing is connected to the "point" node, it would just be stand alone. Therefore I could have one subgraph with the "point" to "meter"/"equip" connections and visually identify the isolated "point".

I also tried something like:

MATCH (p:point)--(e:equip)
RETURN p,e

But that only return the "point" nodes which are somewhat connected to an "equip" node. Not giving me the isolated nodes labeled "point" as well.

Looking forward to your input on this (simple case I guess).

Best!



Solution 1:[1]

The following query will return each point node, along with a list of all its related equip nodes, and another list of all its related meter nodes.

MATCH (p:point)
RETURN p, [(p)--(e:equip) | e] AS es, [(p)--(m:meter) | m] AS ms

Solution 2:[2]

For this specific subset example:

MATCH (p:point)--(e:equip)
RETURN p,e

If you are displaying a graph in the Neo4j Client it will show the output I think you want to see with a simple query like this (many variations on this will work just as well)

MATCH (a:ACTOR), (m:MOVIE)
OPTIONAL MATCH p=(a)--(m)
return a, m, relationships(p)

Translated to your dataset, something like this?

MATCH (p:point), (e:equip)
OPTIONAL MATCH t=(p)--(e)
return p, e, relationships(t)

run this in the neo4j browser and look at the table output, and you'll see the client is simplifying out extra return data as it create the display view (removing nulls, and duplicates)

If your goal is to minimize and restructure the returned data, the best approach may depend on what language you are calling from and how you need/want it formatted, but here is a quick example query using neo4j browser / desktop client that might give you some ideas and help with restructuring what comes back from a cypher query.

MATCH (a:ACTOR), (m:MOVIE)
OPTIONAL MATCH t=(a:ACTOR)--(m:MOVIE)
with collect(distinct a) + collect(distinct m) + collect(relationships(t)) as output
return output

Translated to your dataset, something like this?

MATCH (p:point), (e:equip)
OPTIONAL MATCH t=(p:point)--(e:equip)
with collect(distinct p) + collect(distinct e) + collect(relationships(t)) as output
return output

(compare the table output in neo4j client to the previous query)

Reference article

Solution 3:[3]

match (n) where n:point or n:equip or n:meter  return n

Explanation. You do one match in order to avoid creating a Cartesian product. Using where condition you select modes with either label “point” or “equip”

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cybersam
Solution 2 plastic
Solution 3