Skip to content

Commit

Permalink
Merge ad20b50 into 18abc79
Browse files Browse the repository at this point in the history
  • Loading branch information
jblotus committed Jun 29, 2021
2 parents 18abc79 + ad20b50 commit 526c0eb
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 14 deletions.
15 changes: 10 additions & 5 deletions src/RedisGraph/Edge.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@

final class Edge
{
private string $type;
private string $queryPredicate;
private Node $sourceNode;
private Node $destinationNode;
private ?string $relation;
private ?iterable $properties = [];

public function __construct(
string $type,
string $queryPredicate,
Node $sourceNode,
?string $relation,
Node $destinationNode,
?iterable $properties = []
) {
$this->type = $type;
$this->queryPredicate = $queryPredicate;
$this->sourceNode = $sourceNode;
$this->destinationNode = $destinationNode;
$this->relation = $relation;
Expand All @@ -44,12 +44,12 @@ public function withProperties(iterable $properties): self

public function getType(): string
{
return $this->type;
return $this->queryPredicate;
}

public function toString(): string
{
if ($this->type === 'MERGE') {
if ($this->queryPredicate === 'MERGE') {
return $this->toStringWithMerge();
}
return $this->toStringWithCreate();
Expand Down Expand Up @@ -105,4 +105,9 @@ private function getPropValueWithDataType($propValue)
}
return (int) $propValue;
}

public function getQueryPredicate(): string
{
return $this->queryPredicate;
}
}
6 changes: 4 additions & 2 deletions src/RedisGraph/GraphConstructor.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
class GraphConstructor
{
private string $name;
/** @var Node[] */
private array $nodes = [];
/** @var Edge[] */
private array $edges = [];

public function __construct(string $name)
Expand Down Expand Up @@ -47,10 +49,10 @@ public function getCommitQueryWithMerge(): QueryInterface
{
$query = '';
foreach ($this->nodes as $index => $node) {
$query .= 'MERGE ' . $node->toString() . ' ';
$query .= $node->getQueryPredicate() . ' ' . $node->toString() . ' ';
}
foreach ($this->edges as $index => $edge) {
$query .= 'MERGE ' . $edge->toString() . ' ';
$query .= $edge->getQueryPredicate() . ' ' . $edge->toString() . ' ';
}
return new Query($this->name, trim($query));
}
Expand Down
16 changes: 15 additions & 1 deletion src/RedisGraph/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ final class Node
private ?string $label;
private ?iterable $properties;
private ?string $alias = null;
private ?string $queryPredicate;

public function __construct(?string $label = null, ?iterable $properties = null)
public function __construct(?string $label = null, ?iterable $properties = null, ?string $queryPredicate = null)
{
$this->label = $label;
$this->alias = randomString();
$this->properties = $properties;
$this->queryPredicate = $queryPredicate;
}

public static function create(): self
Expand Down Expand Up @@ -53,6 +55,13 @@ public function withAlias(string $alias): self
return $new;
}

public function withQueryPredicate(string $queryPredicate): self
{
$new = clone $this;
$new->queryPredicate = $queryPredicate;
return $new;
}

public function getAlias(): string
{
return $this->alias;
Expand Down Expand Up @@ -104,4 +113,9 @@ private function getPropValueWithDataType($propValue)
}
return (int) $propValue;
}

public function getQueryPredicate(): string
{
return $this->queryPredicate ?? 'MATCH';
}
}
38 changes: 36 additions & 2 deletions tests/Module/GraphConstructorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ public function shouldCreateQueryObjectWithMergeSuccessfully(): void
$propertiesDestination = ['name' => 'Japan'];
$edgeProperties = ['purpose' => 'pleasure', 'duration' => 'two weeks'];

$person = Node::createWithLabel($labelSource)->withProperties($propertiesSource)->withAlias('CatOwner');
$person = Node::createWithLabel($labelSource)->withProperties($propertiesSource)->withAlias('CatOwner')
->withQueryPredicate('MERGE');
$country = Node::createWithLabelAndProperties($labelDestination, $propertiesDestination)
->withAlias('CatCountry');
->withAlias('CatCountry')
->withQueryPredicate('MERGE');

$edge = Edge::merge($person, 'visited', $country)->withProperties($edgeProperties);

Expand All @@ -75,4 +77,36 @@ public function shouldCreateQueryObjectWithMergeSuccessfully(): void
);
$this->assertEquals('TRAVELLERS', $query->getName());
}

/**
* @test
*/
public function shouldCreateQueryObjectWithMergeOnlyEdgesSuccessfully(): void
{
$labelSource = 'person';
$labelDestination = 'country';

$propertiesSource = ['name' => 'John Doe', 'age' => 33, 'gender' => 'male', 'status' => 'single'];
$propertiesDestination = ['name' => 'Japan'];
$edgeProperties = ['purpose' => 'pleasure', 'duration' => 'two weeks'];

$person = Node::createWithLabel($labelSource)->withProperties($propertiesSource)->withAlias('CatOwner');
$country = Node::createWithLabelAndProperties($labelDestination, $propertiesDestination)
->withAlias('CatCountry');

$edge = Edge::merge($person, 'visited', $country)->withProperties($edgeProperties);

$graph = new GraphConstructor('TRAVELLERS');
$graph->addNode($person);
$graph->addNode($country);
$graph->addEdge($edge);
$query = $graph->getCommitQueryWithMerge();
$this->assertEquals(
'MATCH (CatOwner:person {name: "John Doe", age: 33, gender: "male", status: "single"}) ' .
'MATCH (CatCountry:country {name: "Japan"}) ' .
'MERGE (CatOwner)-[:visited {purpose: "pleasure", duration: "two weeks"}]->(CatCountry)',
$query->getQueryString()
);
$this->assertEquals('TRAVELLERS', $query->getName());
}
}
55 changes: 51 additions & 4 deletions tests/Module/RedisGraphTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,20 @@ public function shouldReturnQueryExecuteResultsSuccessfully(): void
$propertiesDestination = ['name' => 'Japan'];
$edgeProperties = ['purpose' => 'pleasure', 'duration' => 'one weeks'];

$person2 = Node::createWithLabel($labelSource)->withProperties($propertiesSource);
$country2 = Node::createWithLabelAndProperties($labelDestination, $propertiesDestination);
$person2 = Node::createWithLabel($labelSource)->withProperties($propertiesSource)
->withQueryPredicate('MERGE');
$country2 = Node::createWithLabelAndProperties($labelDestination, $propertiesDestination)
->withQueryPredicate('MERGE');
$edge2 = Edge::merge($person2, 'visited', $country2)->withProperties($edgeProperties);

$propertiesSource = ['name' => 'Kedibey', 'age' => 13, 'gender' => 'male', 'status' => 'single'];
$propertiesDestination = ['name' => 'Turkey'];
$edgeProperties = ['purpose' => 'living', 'duration' => 'whole life'];

$person3 = Node::createWithLabel($labelSource)->withProperties($propertiesSource);
$country3 = Node::createWithLabelAndProperties($labelDestination, $propertiesDestination);
$person3 = Node::createWithLabel($labelSource)->withProperties($propertiesSource)
->withQueryPredicate('MERGE');
$country3 = Node::createWithLabelAndProperties($labelDestination, $propertiesDestination)
->withQueryPredicate('MERGE');
$edge3 = Edge::merge($person3, 'visited', $country3)->withProperties($edgeProperties);

$graph = new GraphConstructor('TRAVELLERS');
Expand Down Expand Up @@ -141,6 +145,49 @@ public function shouldReturnQueryExecuteResultsSuccessfully(): void
$this->assertEquals('p.name', $labels[0]);
$this->assertEquals('John Doe', $resultSet[0][0]);

// adding a relationship
$graph = clone $graph;
$edge4 = Edge::merge($person3, 'moved_to', $country3)->withProperties($edgeProperties);
$graph->addEdge($edge4);
$commitQuery = $graph->getCommitQueryWithMerge();
$this->redisGraph->commit($commitQuery);

$matchQueryString = 'MATCH (p:person)-[v:moved_to {purpose:"living"}]->(c:country)
RETURN p.name, p.age, v.duration, c.name';
$matchQuery = new Query('TRAVELLERS', $matchQueryString);

$explain = $this->redisGraph->explain($matchQuery);
$this->assertStringContainsString('Results', $explain);
$this->assertStringContainsString('Filter', $explain);
$this->assertStringContainsString('Conditional Traverse', $explain);
$this->assertStringContainsString('Node By Label Scan', $explain);

$result = $this->redisGraph->query($matchQuery);
ob_start();
$result->prettyPrint();
$content = ob_get_clean();
echo $content;
$expectedLines = <<<EOT
-----------------------------------------
| p.name | p.age | v.duration | c.name |
-----------------------------------------
| Kedibey | 13 | whole life | Turkey |
-----------------------------------------
EOT;
$lines = explode("\n", $expectedLines);

$this->assertStringContainsString($lines[0], $content, 'PrettyPrint');
$this->assertStringContainsString($lines[1], $content, 'PrettyPrint');
$this->assertStringContainsString($lines[2], $content, 'PrettyPrint');
$this->assertStringContainsString($lines[3], $content, 'PrettyPrint');

$resultSet = $result->getResultSet();
$labels = $result->getLabels();
$this->assertEquals('p.name', $labels[0]);
$this->assertEquals('v.duration', $labels[2]);
$this->assertEquals('Kedibey', $resultSet[0][0]);

// @todo delete could be done in setup to reduce test flake
$delete = $this->redisGraph->delete('TRAVELLERS');
$this->assertStringContainsString('Graph removed', $delete);

Expand Down

0 comments on commit 526c0eb

Please sign in to comment.