0
votes

In neo4j my database consists of chains of nodes. For each distinct stucture/layout (does graph theory has a better word?), I want to count the number of chains. For example, the database consists of 9 nodes and 5 relationships as this:

(:a)->(:b)
(:b)->(:a)
(:a)->(:b)
(:a)->(:b)->(:b)

where (:a) is a node with label a. Properties on nodes and relationships are irrelevant.

The result of the counting should be:

------------------------
| Structure        | n |
------------------------
| (:a)->(:b)       | 2 |
| (:b)->(:a)       | 1 |
| (:a)->(:b)->(:b) | 1 |
------------------------

Is there a query that can achieve this?

Appendix

Query to create test data:

create (:a)-[:r]->(:b), (:b)-[:r]->(:a), (:a)-[:r]->(:b), (:a)-[:r]->(:b)-[:r]->(:b)
1
Are there only supposed to be two nodes in the graph a and b, with multiple relationships among them, or are these meant to be separate nodes, with multiple labeled as :a and multiple labeled as :b, meaning there are 4 :a nodes in your example and 5 :b nodes. Are there supposed to be properties on these nodes? Names, for example?InverseFalcon
@InverseFalcon I updated the question to answer your questionsmatthiash

1 Answers

1
votes

EDIT:

Thanks for the clarification.

We can get the equivalent of what you want, a capture of the path pattern using the labels present:

MATCH path = (start)-[*]->(end)
WHERE NOT ()-->(start) and NOT (end)-->()
RETURN [node in nodes(path) | labels(node)[0]] as structure, count(path) as n

This will give you a list of the labels of the nodes (the first label present for each...remember that nodes can be multi-labeled, which may throw off your results).

As for getting it into that exact format in your example, that's a different thing. We could do this with some text functions in APOC Procedures, specifically apoc.text.join().

We would need to first add formatting around the extraction of the first label to add the prefixed : as well as the parenthesis. Then we could use apoc.text.join() to get a string where the nodes are joined by your desired '->' symbol:

MATCH path = (start)-[*]->(end)
WHERE NOT ()-->(start) and NOT (end)-->()
WITH [node in nodes(path) | labels(node)[0]] as structure, count(path) as n
RETURN apoc.text.join([label in structure | '(:' + label + ')'], '->') as structure, n