1
votes

I am trying to get Adjacency-Matrix from neo4j graph. That matrix contains rich features. That mean, if two nodes are connected, then put type of the node ( type is a field of the node ) and edge type into corresponding cell. This is a sample matrix:

[
   [0, 'node_1_type : edge_type : node_2_type', 0],
   ...
]

This is the cypher query which i am going to try. But i don't know how to get edge_type of the connected nodes.

MATCH (n)
WITH collect(n) AS Nodes
WITH [n IN Nodes |
        [m IN Nodes |
            CASE size((n)-[]->(m))
                WHEN 0 THEN 0
                ELSE n.type + ':' + 'edge-type ??'  +  ':' + m.type
            END
        ]
    ] AS AdjacencyMatrix
RETURN AdjacencyMatrix;

Could you please help how to get edge type between connected nodes.

2

2 Answers

0
votes

Since an adjacency matrix is almost by definition, a Cartesian product, I would recommend doing this the straight forward way. Since the end result is a Cartesian product, there is no benefit to avoiding it in this case.

MATCH (a), (b) OPTIONAL MATCH (a)-[r]->(b) 
WITH a,b,
 CASE r 
  WHEN null THEN 0 
  ELSE a.type+":"+TYPE(r)+":"+b.type 
 END as edge 
// collect rows into matrix
return a, edge, b

On the other hand, if for some reason you insist on doing this the hard way, you can actually use pattern matching to extract the info (though, much less efficient as you force Neo4j to needlessly match everything many more times)

MATCH (a), (b) 
WITH a,b,
CASE SIZE((a)-->(b)) 
 WHEN 1 THEN a.type+":"+TYPE(RELATIONSHIPS((a)-->(b)[0])[0])+":"+b.type 
 ELSE 0 
END as edge 
// collect rows into matrix
return a, edge, b

With the magic here obviously being TYPE(RELATIONSHIPS((a)-->(b)[0])[0]), so here's how it works, in the order it is evaluated (part being evaluated in bold)

  1. (a)-->(b) | First pattern match (a)-->(b) (Result is List<Path>)
  2. (a)-->(b)[0] | Take the first result from the List (Result is Path)
  3. RELATIONSHIPS((a)-->(b)[0]) | Extract relationships from the Path (Result List<Relationship>)
  4. RELATIONSHIPS((a)-->(b)[0])[0] | Take the first result from that list (Result is Relationship)
  5. TYPE( RELATIONSHIPS((a)-->(b)[0])[0]) | Take the type of that Relationship (Result is String)
0
votes

Since you can not get a named result inside the CASE use UNWIND:

MATCH (n)
WITH collect(n) AS Nodes
UNWIND Nodes AS n
  UNWIND Nodes AS m
  OPTIONAL MATCH (n)-[r]->(m)
  WITH n, m, 
    CASE r 
      WHEN NULL THEN 0 
      ELSE n.type + ':' + type(r) + ':' + m.type
    END AS e
  WITH m, collect(e) AS row
WITH collect(row) AS AdjacencyMatrix
RETURN AdjacencyMatrix;