BFS - lower bound support
Summary: This is not a very important functionality, but it turned out simple to do, so let's add it to have a consistent query support. Reviewers: buda, teon.banek Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D862
This commit is contained in:
parent
e6c3d42e02
commit
d0fb4d7242
@ -436,10 +436,8 @@ destination node. Furthermore, it's possible to find multiple paths to multiple
|
||||
nodes regardless of their length. Also, it is possible to simply go through a node's
|
||||
neighbourhood in breadth-first manner.
|
||||
|
||||
It is fair to say there are a few drawbacks too. Currently, it isn't possible to get
|
||||
all shortest paths to a single node using Memgraph's breadth-first expansion. Also
|
||||
property maps (in curly brackets) are not supported with a BFS. These features will
|
||||
most likely be included in subsequent Memgraph releases.
|
||||
Currently, it isn't possible to get all shortest paths to a single node using
|
||||
Memgraph's breadth-first expansion.
|
||||
|
||||
#### UNWIND
|
||||
|
||||
|
@ -570,8 +570,6 @@ antlrcpp::Any CypherMainVisitor::visitVariableExpansion(
|
||||
upper = ctx->expression()[1]->accept(this);
|
||||
}
|
||||
|
||||
if (is_bfs && lower)
|
||||
throw SemanticException("BFS does not support lower bounds");
|
||||
return std::make_tuple(is_bfs, lower, upper);
|
||||
}
|
||||
|
||||
|
@ -927,6 +927,10 @@ class ExpandBreadthFirstCursor : public query::plan::Cursor {
|
||||
SwitchAccessor(vertex, self_.graph_view_);
|
||||
processed_.emplace(vertex, std::experimental::nullopt);
|
||||
expand_from_vertex(vertex);
|
||||
lower_bound_ = self_.lower_bound_
|
||||
? EvaluateInt(evaluator, self_.lower_bound_,
|
||||
"Min depth in breadth-first expansion")
|
||||
: 1;
|
||||
upper_bound_ = self_.upper_bound_
|
||||
? EvaluateInt(evaluator, self_.upper_bound_,
|
||||
"Max depth in breadth-first expansion")
|
||||
@ -963,6 +967,9 @@ class ExpandBreadthFirstCursor : public query::plan::Cursor {
|
||||
if (static_cast<int>(edge_list.size()) < upper_bound_)
|
||||
expand_from_vertex(expansion.second);
|
||||
|
||||
if (static_cast<int64_t>(edge_list.size()) < lower_bound_)
|
||||
continue;
|
||||
|
||||
// place destination node on the frame, handle existence flag
|
||||
if (self_.existing_node_) {
|
||||
TypedValue &node = frame[self_.node_symbol_];
|
||||
@ -990,8 +997,9 @@ class ExpandBreadthFirstCursor : public query::plan::Cursor {
|
||||
GraphDbAccessor &db_;
|
||||
const std::unique_ptr<query::plan::Cursor> input_cursor_;
|
||||
|
||||
// maximum depth of the expansion. calculated on each pull
|
||||
// from the input, the initial value is irrelevant.
|
||||
// Depth bounds. Calculated on each pull from the input, the initial value is
|
||||
// irrelevant.
|
||||
int lower_bound_{-1};
|
||||
int upper_bound_{-1};
|
||||
|
||||
// maps vertices to the edge they got expanded from. it is an optional
|
||||
|
@ -1,6 +1,6 @@
|
||||
Feature: Bfs
|
||||
|
||||
Scenario: Test match BFS depth blocked
|
||||
Scenario: Test match BFS upper bound
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
@ -15,6 +15,21 @@ Feature: Bfs
|
||||
| '0' | '1.1' |
|
||||
| '0' | '1.2' |
|
||||
|
||||
Scenario: Test match BFS lower bound
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
"""
|
||||
CREATE (n {a:'0'})-[:r]->({a:'1.1'})-[:r]->({a:'2.1'})-[:r]->({a:'3.1'})
|
||||
"""
|
||||
When executing query:
|
||||
"""
|
||||
MATCH (n {a:'0'})-[*bfs 2..]->(m) RETURN n.a, m.a
|
||||
"""
|
||||
Then the result should be:
|
||||
| n.a | m.a |
|
||||
| '0' | '2.1' |
|
||||
| '0' | '3.1' |
|
||||
|
||||
Scenario: Test match BFS filtered
|
||||
Given an empty graph
|
||||
And having executed:
|
||||
|
Loading…
Reference in New Issue
Block a user