0

I need to take subgraph of given depth stating from some vertex using bfs. I've tried code similar to following

MATCH (p:Node {id: '1'}) CALL apoc.path.subgraphAll(p, {minLevel: 0, maxLevel: 1}) YIELD nodes, relationships RETURN nodes, relationships;

but it seems to be extremely slow comparing to cypher queries (neo4j 4.3.3) What is the best way to take subgraphs with bfs in neo4j?

Graphileon
  • 5,275
  • 3
  • 17
  • 31
schernichkin
  • 1,013
  • 7
  • 15
  • Can you share the cypher queries you compared it with? – Graphileon Sep 22 '21 at 04:01
  • Query to return all immediate neighbors may looks like MATCH q=(:Node {id: '1'})-[:Edge*0..1]-(:Node) return nodes(q), relations(q). For depth 2 [:Edge*0..2]. It will return more data than just bfs, because it will return all paths, not just graph, but even so it works faster. – schernichkin Sep 22 '21 at 22:11

1 Answers1

1

I did some tests with our own test store , and a depth of 4

using apoc

//subgraph apoc 4
MATCH (n) WHERE id(n)=30341
CALL apoc.path.subgraphAll(n, {
    minLevel: 0,
    maxLevel: 4
})
YIELD nodes, relationships
RETURN size(nodes),size(relationships)

Results with apoc

getting the same result in cypher requires this query

// subgraph cypher 4
MATCH path=(n)-[*0..4]-(m) WHERE id(n)=30341
UNWIND nodes(path) AS node
UNWIND relationships(path) AS rel
WITH COLLECT ( DISTINCT node) AS pathNodes,
     COLLECT ( DISTINCT rel ) AS pathRels
MATCH (n1)-[r]-(n2)
WHERE n1 IN pathNodes AND n2 IN pathNodes 
      AND id(n1) >= id(n2)
      AND NOT r IN pathRels
WITH pathNodes,pathRels, COLLECT(r) AS rels
RETURN size(pathNodes),size(pathRels+rels)

Results cypher

which takes a lot longer.

Graphileon
  • 5,275
  • 3
  • 17
  • 31
  • It can be slower on large graphs because it return all paths in graph. But there is a bug in subgraphAll anyway, which made it сomputational complexity quadratic on result. – schernichkin Sep 23 '21 at 10:14