PGX 20.1.1
Documentation

Creating Subgraphs from Loaded Graphs

The goal of this guide is to help you understand how to create a subgraph, based on an already loaded graph. First, we will introduce filter expressions, which are two different ways to create a subgraph in PGX. Then we will show how to create a bipartite subgraph based on a vertex collection that specifies the left set of the bipartite graph.

Recap: Load a Graph into Memory

To load a graph, you need a graph config stored in an accessible location that points to a graph that is accessible by PGX. If your graph is not stored on the same machine as the one where PGX runs, make sure that you can access it.

You can read a graph like this:

var g = session.readGraphWithProperties("examples/graphs/sample.csv.json")
import oracle.pgx.api.*;

PgxSession session = Pgx.createSession("my-session");
PgxGraph g = session.readGraphWithProperties("examples/graphs/sample.csv.json");

Once the graph is loaded, you can become familiar with the semantics of our filter expressions by reading the filter expression reference or you can use the following introduction to understand the concept of filter expressions in PGX.

An Introduction to Filter Expressions

Filter expressions in PGX are expressions that are evaluated for either each vertex or each edge. The expression can define some predicates that a vertex or edge has to fulfill in order to be contained in the result, in this case a subgraph.

This graph is based on the sample graph that is also used for other tutorials and it is part of the PGX download package.

sample graph

The edge filter expression

src.prop1 == 10

conveys that each edge where the source vertex's property prop1 equals the value 10 will match the expression. The following edges will be matched by this expression:

sample graph with highlighted edges

which results in the following subgraph:

sample filtered graph

The vertex filter expression

vertex.prop1 < 10

expresses that each vertex where the property prop1 is less than 10 will match the expression. The following vertices will be matched by this expression:

sample graph with highlighted vertices

which results in the following subgraph:

sample filtered graph

Refer to the filter reference for more information about filter expressions in PGX.

Creating a Subgraph Based on a Filter in PGX

You can either use the shell to create a filtered subgraph and interact with it or you can use our Java API (local and remote) or the REST interface directly, or PGQL query language.

Example for Creating and Using an Edge Filter

var subgraph = g.filter(EdgeFilter.fromExpression("src.prop1 == 10"))
import oracle.pgx.filter.expressions.*;
...
PgxGraph subgraph = g.filter(EdgeFilter.fromExpression("src.prop1 == 10"));

Example for Creating and Using a Vertex Filter

var subgraph = g.filter(VertexFilter.fromExpression("vertex.prop1 < 10"))
import oracle.pgx.filter.expressions.*;
...
PgxGraph subgraph = g.filter(VertexFilter.fromExpression("vertex.prop1 < 10"));

Create a Subgraph Based on a More Complex Filter

This example focuses on a slightly more complex filter, which uses some special features of our filter expressions. One such feature is the outDegree() function. It calculates the number of outgoing edges for an identifier (src or dst). The following filter expression matches all edges where the destination vertex has an outDegree higher than 1 and an edge property cost higher than 50.

dst.outDegree() > 1 && edge.cost > 50

There is only one edge in the sample graph which matches this filter expression:

sample graph with highlighted edges

The resulting subgraph looks like this:

sample filtered graph

Combining Filters

It is also possible to combine vertex filters with edge filters.

Both filters are evaluated separately and afterwards merged by either creating a union of the results or by intersecting the results.

Creating a Union of Two Filters

Creating the union of the edge filter:

src.prop1 == 10

and the vertex filter:

vertex.prop1 < 10

will result in the following graph:

sample union_graph

var edgeFilter = EdgeFilter.fromExpression("src.prop1 == 10")
var vertexFilter = VertexFilter.fromExpression("vertex.prop1 < 10")
var filter = edgeFilter.union(vertexFilter)
var subgraph = g.filter(filter)
import oracle.pgx.api.filter.*;
...
EdgeFilter edgeFilter = EdgeFilter.fromExpression("src.prop1 == 10");
VertexFilter vertexFilter = VertexFilter.fromExpression("vertex.prop1 < 10");
GraphFilter filter = edgeFilter.union(vertexFilter);

PgxGraph subgraph = g.filter(filter);

Creating an Intersection of Two Filters

Creating the intersection of the filters mentioned above will result in the following graph, that only consists of a single vertex:

sample intersection_graph

var edgeFilter = EdgeFilter.fromExpression("src.prop1 == 10")
var vertexFilter = VertexFilter.fromExpression("vertex.prop1 < 10")
var filter = edgeFilter.intersect(vertexFilter)
var subgraph = g.filter(filter)
import oracle.pgx.filter.expressions.*;
...
EdgeFilter edgeFilter = EdgeFilter.fromExpression("src.prop1 == 10");
VertexFilter vertexFilter = VertexFilter.fromExpression("vertex.prop1 < 10");
GraphFilter filter = edgeFilter.intersect(vertexFilter);

PgxGraph subgraph = g.filter(filter);

Creating a Set of Vertices or Edges Using a Filter

Instead of using filters to create a subgraph they can also be used to only select a set of vertices or edges from a graph.

Creating a vertex set on the sample graph using the vertex filter expression

vertex.prop1 < 10

will yield the following set:

PgxVertex with ID 99
PgxVertex with ID 333

These sets can for example be used to create a bipartite subgraph (see below).

Example for Creating a Vertex Set

var vertices = g.getVertices(VertexFilter.fromExpression("vertex.prop1 < 10"))
==> PgxVertex with ID 99
==> PgxVertex with ID 333
import oracle.pgx.api.*;
import oracle.pgx.filter.expressions.*;
...
VertexSet<Integer> = g.getVertices(VertexFilter.fromExpression("vertex.prop1 < 10"));

Example for Creating an Edge Set

var edges = g.getEdges(EdgeFilter.fromExpression("src.prop1 == 10"))
==> PgxEdge with ID 0
==> PgxEdge with ID 1
import oracle.pgx.api.*;
import oracle.pgx.filter.expressions.*;
...
EdgeSet = g.getEdges(EdgeFilter.fromExpression("src.prop1 == 10"));

Create a Bipartite Subgraph Based on a Vertex List

The second way to create a subgraph is to specify a set of vertices and create a bipartite subgraph based on those vertices. The specified vertices will be used as the left-hand side of the bipartite subgraph. A bipartite subgraph only has edges between the left set and the other vertices (essentially the right-hand side), but not in between those groups (e.g. no edges from a left set vertex to another left set vertex and no edges between a right-hand side vertex to another right-hand side vertex). In PGX, vertices that are isolated because all the edges leading to and from it were deleted will not be part of the bipartite subgraph.

This is an example of a bipartite subgraph, without any properties shown:

bipartite sample graph without properties

Given the simple graph example from earlier, we can use PGX to create a bipartite subgraph based on a couple of vertices. Before creating the bipartite subgraph, however, we first need to create a new vertex collection and then fill it with the vertices we want to have on the left-hand side.

pgx> var s = g.createVertexSet()
pgx> s.addAll(333, 99)
pgx> var bipartite = g.bipartiteSubGraphFromLeftSet(s)
==> PGX Bipartite Graph named sample-10-sub-graph-5
import oracle.pgx.api.*;
...

VertexSet<Integer> s = g.createVertexSet();
s.addAll(333, 99);
BipartiteGraph bipartite = g.bipartiteSubGraphFromLeftSet(s);

When you create the subgraph PGX will automatically create a new boolean vertex property that stores whether a vertex is on the left side or not. You can then specify what the new vertex property should be called. The name must not have been previously used for another vertex property on this graph.

The resulting bipartite subgraph looks like this:

bipartite subgraph based on sample

As you may have noticed, the vertex with the ID 1908 is not in the bipartite subgraph. Since the only edge connecting that vertex to the graph was the one from 128 to 1908 that edge would violate the bipartite properties of the subgraph, the edge was removed. The 1908 vertex had no other connection to the graph and was removed as well. Moreover, the edge from the vertex with the ID 128 to the vertex with ID 99 is not present in the bipartite subgraph, because edges are only allowed to go from left to right (and not from right to left).