neo4jcyphermedical

Cypher: unable to traverse through same nodes


I am new to Neo4J/Cypher Queries, I want to map only from node to node but I am unable to achieve that. Basically, I am trying to explore UMLS data, in which we have to find the Semantic nodes which are in common or which have a parent-child relationship.

Here is the query I tried:

Match (:Code{CODE:"A41.9"})-[]-(c:Concept)-[r*..3]-(n:Concept)-[:PT]-(t:Term)
Optional Match (c)-[]-(:Semantic{name: "Disease or Syndrome"})
return distinct n.CODE, t.name;

If I observe the graph, sometimes the concept path is not directly connected. It is connecting from Semantic or other nodes that are available in the graph.

I expect the (c:Concept)-[r*..3]-(n:Concept) to only go from concept to concept only up to 3 levels.

Anyone trying UMLS please connect lets solve together and explore medical data. Thank you


Solution

  • The pattern (c:Concept)-[r*..3]-(n:Concept) does not restrict the nodes within that var-length path, so those nodes can be anything, provided that the start and end nodes of that subpath are :Concept nodes.

    If you want to restrict the nodes in that path such that they must be all be :Concept nodes, there are a few ways you could do this.

    If you are using Neo4j 5.9 or later, then you can use quantified path patterns instead, and provide a pattern that restricts the labels of the nodes expanded

    Here is the same segment expressed with QPP, restricting that the nodes in the quantified path must only be :Concept nodes:

    (c:Concept {id:1}) ((:Concept)--(:Concept)){1,3} (n:Concept)

    If you want to instead stick with the variable-length pattern syntax, then you must break out that segment into its own subpath with path variable, and provide a list predicate to restrict the nodes in that var-length path:

    Match (:Code{CODE:"A41.9"})-[]-(c:Concept), path = (c)-[r*..3]-(n:Concept), (n)-[:PT]-(t:Term)
    WHERE all(node IN nodes(path) WHERE node:Concept)
    ...