cypher - How can I calculate the path between two nodes with hops in range (1,5) (neo4j) ? -
i'm trying find possible path between 2 nodes. i've used few cypher queries required job take lot of time if hops increases. query
match p = (n{name:"node1"})-[:route*1..5]-(b{name:"node2"}) return p
also if use shortestpath
limits result if path minimum hop found. don't results 2 or more 2 hops if direct connection (1 hop) found between nodes.
match p = shortestpath((n{name:"node1"})-[:route*1..5]-(b{name:"node2"})) return p
and if increase hop 2 or more throws exception.
shortestpath(...) not support minimal length different 0 or 1
is there other alternative framework or algorithm path minimum time ?
p.s. i'm looking in order of ms. queries hops greater 3 takes few seconds complete.
i gather trying speed original query involving variable-length paths. shortestpath
function not appropriate query, literally tries find shortest path -- not all paths length.
the execution plan original query (using sample data) looks this:
+-----------------------+----------------+------+---------+-------------------+---------------------------------------------+ | operator | estimated rows | rows | db hits | identifiers | other | +-----------------------+----------------+------+---------+-------------------+---------------------------------------------+ | +produceresults | 0 | 1 | 0 | p | p | | | +----------------+------+---------+-------------------+---------------------------------------------+ | +projection | 0 | 1 | 0 | anon[30], b, n, p | projectedpath(set(anon[30], n),) | | | +----------------+------+---------+-------------------+---------------------------------------------+ | +filter | 0 | 1 | 2 | anon[30], b, n | n.name == { autostring0} | | | +----------------+------+---------+-------------------+---------------------------------------------+ | +varlengthexpand(all) | 0 | 2 | 7 | anon[30], b, n | (b)<-[:route*]-(n) | | | +----------------+------+---------+-------------------+---------------------------------------------+ | +filter | 0 | 1 | 3 | b | b.name == { autostring1} | | | +----------------+------+---------+-------------------+---------------------------------------------+ | +allnodesscan | 3 | 3 | 4 | b | | +-----------------------+----------------+------+---------+-------------------+---------------------------------------------+
so, original query scanning through every node find node(s) match b
pattern. then, expands all variable-length paths starting @ b
. , filters paths find one(s) end node matches pattern n
.
here few suggestions should speed query, although you'll have test on data see how much:
- give each node label. example,
foo
. create index can speed search end nodes. example:
create index on :foo(name);
modify query force use of index on both end nodes. example:
match p =(n:foo { name:"node1" })-[:route*1..5]-(b:foo { name:"node2" }) using index n:foo(name) using index b:foo(name) return p;
after above changes, execution plan is:
+-----------------+------+---------+-----------------------------+-----------------------------+ | operator | rows | db hits | identifiers | other | +-----------------+------+---------+-----------------------------+-----------------------------+ | +columnfilter | 1 | 0 | p | keep columns p | | | +------+---------+-----------------------------+-----------------------------+ | +extractpath | 1 | 0 | anon[33], anon[34], b, n, p | | | | +------+---------+-----------------------------+-----------------------------+ | +patternmatcher | 1 | 3 | anon[33], anon[34], b, n | | | | +------+---------+-----------------------------+-----------------------------+ | +schemaindex | 1 | 2 | b, n | { autostring1}; :foo(name) | | | +------+---------+-----------------------------+-----------------------------+ | +schemaindex | 1 | 2 | n | { autostring0}; :foo(name) | +-----------------+------+---------+-----------------------------+-----------------------------+
this query plan uses index directly b
, n
nodes -- without scanning. this, itself, should provide speed improvement. , plan uses "patternmatcher" find variable-length paths between end nodes. have try query out see how efficient "patternmatcher" in doing that.
Comments
Post a Comment