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:
florijan 2017-10-06 09:33:12 +02:00
parent e6c3d42e02
commit d0fb4d7242
4 changed files with 28 additions and 9 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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: