Search code examples
neo4jcypherlimit

neo4j how to query with variable nodes in between limiting the number of relations between subsequent nodes?


Consider a query similar to this:

MATCH p=(b:label{ID:"M04"})-[r:Edge*2..2]-(d:label{ID:"S02"})
RETURN p LIMIT 10

Let me call the intermediate node c. The relations from b to the intermediate nodes and to the final node d are all of the same type Edge and have the property EdgeID. From one node to another there are different relations of type Edge each one with a different EdgeID property value. To the next node there are other relations of the same type and most of them having the same value of the property EdgeID.

For example the graph is similar to that:

(b)-[:Edge{EdgeID:1}]->(c)-[:Edge{EdgeID:1}]->(d)
(b)-[:Edge{EdgeID:2}]->(c)-[:Edge{EdgeID:2}]->(d)
(b)-[:Edge{EdgeID:3}]->(c)-[:Edge{EdgeID:3}]->(d)
....

The query returns many relations from b to c but a single relation from c to d

(b)-[:Edge{EdgeID:1}]->(c)-[:Edge{EdgeID:1}]->(d)
(b)-[:Edge{EdgeID:2}]->(c)-[:Edge{EdgeID:1}]->(d)
(b)-[:Edge{EdgeID:3}]->(c)-[:Edge{EdgeID:1}]->(d)
....

I want to return the paths with the relations having the same EdgeID. So for example with LIMIT 1 I want to return only one among the above rows, for example

(b)-[:Edge{EdgeID:123123}]->(c)-[:Edge{EdgeID:123123}]->(d)

(not necessarily that ID)

With LIMIT 2 I want to return two, for example:

(b)-[:Edge{EdgeID:123123}]->(c)-[:Edge{EdgeID:123123}]->(d)
(b)-[:Edge{EdgeID:872346}]->(c)-[:Edge{EdgeID:872346}]->(d)

How can I do that?


Solution

  • You should be able to add the condition that the relationships in the path have the same property value:

    MATCH p=(b:label{ID:"M04"})-[:Edge*2]-(d:label{ID:"S02"})
    WHERE relationships(p)[0].EdgeID = relationships(p)[1].EdgeID
    RETURN p LIMIT 10
    

    And if you need this kind of restriction to be in place for arbitrary length paths, then you can do:

    MATCH p=(b:label{ID:"M04"})-[:Edge*6]-(d:label{ID:"S02"})
    WITH p, relationships(p)[0].EdgeID as edgeID
    WHERE all(rel in tail(relationships(p)) WHERE rel.EdgeID = edgeID)
    RETURN p LIMIT 10