PGX 21.1.1

Documentation

Documentation

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.

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");

session= pypgx.get_session(session_name="my-session") g = session.read_graph_with_properties("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.

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.

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:

which results in the following subgraph:

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:

which results in the following subgraph:

Refer to the filter reference for more information about filter expressions 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.

var subgraph = g.filter(EdgeFilter.fromExpression("src.prop1 == 10"))

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

subgraph = g.filter(EdgeFilter("src.prop1 == 10"))

var subgraph = g.filter(VertexFilter.fromExpression("vertex.prop1 < 10"))

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

subgraph = g.filter(VertexFilter("vertex.prop1 < 10"))

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:

The resulting subgraph looks like this:

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 the union of the edge filter:

src.prop1 == 10

and the vertex filter:

vertex.prop1 < 10

will result in the following 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);

edge_filter = EdgeFilter("src.prop1 == 10") vertex_filter = VertexFilter("vertex.prop1 < 10") filter = edge_filter.union(vertex_filter) subgraph = g.filter(filter)

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

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

edge_filter = EdgeFilter("src.prop1 == 10") vertex_filter = VertexFilter("vertex.prop1 < 10") filter = edge_filter.intersect(vertex_filter) subgraph = g.filter(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).

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> vertices= g.getVertices(VertexFilter.fromExpression("vertex.prop1 < 10"));

vertices = g.get_vertices(filter_expr= VertexFilter("vertex.prop1 < 10"))

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"));

edge_set= g.get_edges(filter_expr=EdgeFilter("src.prop1 == 10"))

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:

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

s = create_vertex_set() s.add_all([333,99]) bipartite = g.bipartite_sub_graph_from_left_set(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:

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).