问题
I've recently asked about how to find all paths between two types os nodes in a way where all the edges in the path had the same attribute (like the same ID). This would be something like:
MATCH (a {type: 'cin1'})-[rels:Next*1.. {value: 1}]->(b {type: 'cancer'})
RETURN (a), (b)
where instead of having value: 1 I would have value: same for all edges.
I found a way to solve this by using something like this (as answered in my other question):
MATCH (a:Label {type: 'cin1'})
MATCH (b:Label {type: 'cancer'})
MATCH shortestPath((a)-[rels:Next*1..20]->(b))
WHERE ALL(r in tail(rels) WHERE (head(rels)).value = r.value)
RETURN (a), (b)
The problem I'm having is that this approach first create all the possible different paths to then filter them, which in my case creates exponentially many paths. For example, take the following graph
:
The approach given will first match all the paths:
id:1 -> id:1 -> id:1
id:1 -> id:2 -> id:1
id:1 -> id:1 -> id:2
id:1 -> id:2 -> id:2
id:1 -> id:2 -> id:3
...
And only then filter these options to return 1->1->1, 2->2->2, 3->3->3 and so on. Therefore it turns out that this approach is very not effective, and I wonder if there is an easier way.
回答1:
As far as optimizations, I'd first look at ways to optimize quick matches on start and end nodes, as that should significantly reduce the nodes scanned.
My hunch is that you probably aren't indexing on :Label.type, and if that's your primary means of matching to nodes, this is probably something to consider and test.
It may also be effective to see if you can add labels on your start or end nodes. At the least it seems like :Cancer could likely be applied effectively, though if this is meant to be a more general medical app this kind of query would need to be effective for many diseases, so I'm not sure if this is feasible for you.
In that case I think your best bet is to optimize the shortestPath(), and PROFILE your query to ensure that your WHERE ALL clause is being used during calculation of the shortestPath, and not as a filter after exhaustive searches (see Shortest Path and Shortest Path Planning). If profiling reveals that it's being used as a filter rather than while constructing shortest path, you'll want to see if you can pick a more efficient predicate shortest path will fail fast for non-matching patterns.
来源:https://stackoverflow.com/questions/38183686/finding-specific-path-in-neo4j-quickly