PGX 20.2.2
Documentation

Building Graphs from Scratch

For small example graphs the effort of writing the graph data to a file and loading it with a configuration might be too big.

This guide shows an alternative way of creating graphs using the GraphBuilder interface. This interface allows users to create small graphs programmatically.

Creating a Simple Graph

The starting point for creating graphs is the GraphBuilder class which accumulates the vertex and edge data of the new graph. After all changes have been added a PgxGraph can be created out of the accumulated vertices and edges. the GraphBuilder supports two generation strategies for creating vertices and edges IDs: USER_IDS (the default value) and AUTO_GENERATED.

Let us see how that works by creating the simple sample graph from the previous graph loading guide programmatically:

var builder = session.createGraphBuilder()

builder.addEdge(1, 2)
builder.addEdge(2, 3)
builder.addEdge(2, 4)
builder.addEdge(3, 4)
builder.addEdge(4, 2)

var graph = builder.build()
import oracle.pgx.api.*;

PgxSession session = Pgx.createSession("example");
GraphBuilder<Integer> builder = session.createGraphBuilder();

builder.addEdge(1, 2);
builder.addEdge(2, 3);
builder.addEdge(2, 4);
builder.addEdge(3, 4);
builder.addEdge(4, 2);

PgxGraph graph = builder.build();
from pypgx import get_session

session = get_session(session_name="example")
builder = session.create_graph_builder()
builder.add_edge(1, 2)
builder.add_edge(2, 3)
builder.add_edge(2, 4)
builder.add_edge(3, 4)
builder.add_edge(4, 2)

There are a couple of things to notice here:

First, a call to addEdge consists of the new, unique edge ID, the source vertex ID and the destination vertex ID.

Second, no graph config is needed. Everything needed to know is extracted from the data that is available.

Third, notice that we only added edges and did not add any vertices. This is because any vertices that not already exist will be added on the fly as edges are created.

The resulting graph is a session bound, transient graph, which can be queried and analyzed just as if the graph was loaded from a file.

The graph can also be stored to a file in a format recognized by PGX. See the Store Graph Data to Disk guide for more information on that.

Adding a Vertex Property

Now, how does the code look like if we want to add a vertex property? For this the GraphBuilder offers a fluid interface:

var builder = session.createGraphBuilder()

builder.addVertex(1).setProperty("double-prop", 0.1)
builder.addVertex(2).setProperty("double-prop", 2.0)
builder.addVertex(3).setProperty("double-prop", 0.3)
builder.addVertex(4).setProperty("double-prop", 4.56789)

builder.addEdge(1, 2)
builder.addEdge(2, 3)
builder.addEdge(2, 4)
builder.addEdge(3, 4)
builder.addEdge(4, 2)

var graph = builder.build()
import oracle.pgx.api.*;

PgxSession session = Pgx.createSession("example");
GraphBuilder<Integer> builder = session.createGraphBuilder();

builder.addVertex(1).setProperty("double-prop", 0.1);
builder.addVertex(2).setProperty("double-prop", 2.0);
builder.addVertex(3).setProperty("double-prop", 0.3);
builder.addVertex(4).setProperty("double-prop", 4.56789);

builder.addEdge(1, 2);
builder.addEdge(2, 3);
builder.addEdge(2, 4);
builder.addEdge(3, 4);
builder.addEdge(4, 2);

PgxGraph graph = builder.build();
from pypgx import get_session

session = get_session(session_name="example")
builder = session.create_graph_builder()

builder.add_vertex(1).set_property("double-prop", 0.1)
builder.add_vertex(2).set_property("double-prop", 2.0)
builder.add_vertex(3).set_property("double-prop", 0.3)
builder.add_vertex(4).set_property("double-prop", 4.56789)

builder.add_edge(1, 2)
builder.add_edge(2, 3)
builder.add_edge(2, 4)
builder.add_edge(3, 4)
builder.add_edge(4, 2)

graph = builder.build()

Now we need to add the vertices separately, as we want to assign property values to them.

As previously stated, we don't need to write a graph config. Therefore we do not need to specify the type of the property anywhere. The type of a property is automatically determined from the value of the first mention of the property.

If the value for a property is missing for a vertex or edge, a default value is assumed. This is 0 (or the respective equivalent) for numeric properties, false for boolean properties, 1.1.1970 00:00:00 for date properties and null for string properties.

Multiple calls to setProperty can be chained to set multiple property values at once.

Use Strings as Vertex Identifiers

All of the previous examples had integer vertex IDs to identify a vertex, which is the default in PGX. As with graphs loaded from file or database, the type of the vertex ID can also be a long or a string.

For this we need to specify the vertex ID type when we create the GraphBuilder.

Let's recreate the graph with string vertex IDs:

var builder = session.<String>createGraphBuilder(IdType.STRING)

builder.addVertex("vertex 1").setProperty("double-prop", 0.1)
builder.addVertex("vertex 2").setProperty("double-prop", 2.0)
builder.addVertex("vertex 3").setProperty("double-prop", 0.3)
builder.addVertex("vertex 4").setProperty("double-prop", 4.56789)

builder.addEdge("vertex 1", "vertex 2")
builder.addEdge("vertex 2", "vertex 3")
builder.addEdge("vertex 2", "vertex 4")
builder.addEdge("vertex 3", "vertex 4")
builder.addEdge("vertex 4", "vertex 2")

var graph = builder.build()
import oracle.pgx.api.*;
import oracle.pgx.common.types.IdType;

PgxSession session = Pgx.createSession("example");
GraphBuilder<String> builder = session.createGraphBuilder(IdType.STRING);

builder.addVertex("vertex 1").setProperty("double-prop", 0.1);
builder.addVertex("vertex 2").setProperty("double-prop", 2.0);
builder.addVertex("vertex 3").setProperty("double-prop", 0.3);
builder.addVertex("vertex 4").setProperty("double-prop", 4.56789);

builder.addEdge("vertex 1", "vertex 2");
builder.addEdge("vertex 2", "vertex 3");
builder.addEdge("vertex 2", "vertex 4");
builder.addEdge("vertex 3", "vertex 4");
builder.addEdge("vertex 4", "vertex 2");

PgxGraph graph = builder.build();
from pypgx import get_session

session = get_session(session_name="example")
builder = session.create_graph_builder(id_type='string')
builder.add_vertex("vertex 1").set_property("double-prop", 0.1)
builder.add_vertex("vertex 2").set_property("double-prop", 2.0)
builder.add_vertex("vertex 3").set_property("double-prop", 0.3)
builder.add_vertex("vertex 4").set_property("double-prop", 4.56789)

builder.add_edge("vertex 1", "vertex 2")
builder.add_edge("vertex 2", "vertex 3")
builder.add_edge("vertex 2", "vertex 4")
builder.add_edge("vertex 3", "vertex 4")
builder.add_edge("vertex 4", "vertex 2")

graph = builder.build()

Shortcut for Creating Edges with Previously Created Vertices

As it can be very repetative to always enter the full vertex ID when adding an edge, a shortcut can be used. For this a reference to the vertex can be obtained as it is created which can be used in the addEdge statement afterwards.

var builder = session.<String>createGraphBuilder(IdType.STRING)

var v1 = builder.addVertex("vertex 1").setProperty("double-prop", 0.1)
var v2 = builder.addVertex("vertex 2").setProperty("double-prop", 2.0)
var v3 = builder.addVertex("vertex 3").setProperty("double-prop", 0.3)
var v4 = builder.addVertex("vertex 4").setProperty("double-prop", 4.56789)

builder.addEdge(v1, v2)
builder.addEdge(v2, v3)
builder.addEdge(v2, v4)
builder.addEdge(v3, v4)
builder.addEdge(v4, v2)

var graph = builder.build()
import oracle.pgx.api.*;
import oracle.pgx.common.types.IdType;

PgxSession session = Pgx.createSession("example");
GraphBuilder<String> builder = session.createGraphBuilder(IdType.STRING);

VertexBuilder<String> v1 = builder.addVertex("vertex 1").setProperty("double-prop", 0.1);
VertexBuilder<String> v2 = builder.addVertex("vertex 2").setProperty("double-prop", 2.0);
VertexBuilder<String> v3 = builder.addVertex("vertex 3").setProperty("double-prop", 0.3);
VertexBuilder<String> v4 = builder.addVertex("vertex 4").setProperty("double-prop", 4.56789);

builder.addEdge(v1, v2);
builder.addEdge(v2, v3);
builder.addEdge(v2, v4);
builder.addEdge(v3, v4);
builder.addEdge(v4, v2);

PgxGraph graph = builder.build();
from pypgx import get_session
session = get_session(session_name="example")
builder = session.create_graph_builder(id_type='string')

v1 = builder.add_vertex("vertex 1").set_property("double-prop", 0.1)
v2 = builder.add_vertex("vertex 2").set_property("double-prop", 2.0)
v3 = builder.add_vertex("vertex 3").set_property("double-prop", 0.3)
v4 = builder.add_vertex("vertex 4").set_property("double-prop", 4.56789)

builder.add_edge(v1, v2)
builder.add_edge(v2, v3)
builder.add_edge(v2, v4)
builder.add_edge(v3, v4)
builder.add_edge(v4, v2)

graph = builder.build()

Add an Edge Property and Label

Finally, we want to add an edge property and an edge label to the graph.

var builder = session.<String>createGraphBuilder(IdType.STRING)

var v1 = builder.addVertex("vertex 1").setProperty("double-prop", 0.1)
var v2 = builder.addVertex("vertex 2").setProperty("double-prop", 2.0)
var v3 = builder.addVertex("vertex 3").setProperty("double-prop", 0.3)
var v4 = builder.addVertex("vertex 4").setProperty("double-prop", 4.56789)

builder.addEdge(v1, v2).setProperty("edge-prop", "edge_prop_1_2").setLabel("label")
builder.addEdge(v2, v3).setProperty("edge-prop", "edge_prop_2_3").setLabel("label")
builder.addEdge(v2, v4).setProperty("edge-prop", "edge_prop_2_4").setLabel("label")
builder.addEdge(v3, v4).setProperty("edge-prop", "edge_prop_3_4").setLabel("label")
builder.addEdge(v4, v2).setProperty("edge-prop", "edge_prop_4_2").setLabel("label")

var graph = builder.build()
import oracle.pgx.api.*;
import oracle.pgx.common.types.IdType;

PgxSession session = Pgx.createSession("example");
GraphBuilder<String> builder = session.createGraphBuilder(IdType.STRING);

VertexBuilder<String> v1 = builder.addVertex("vertex 1").setProperty("double-prop", 0.1);
VertexBuilder<String> v2 = builder.addVertex("vertex 2").setProperty("double-prop", 2.0);
VertexBuilder<String> v3 = builder.addVertex("vertex 3").setProperty("double-prop", 0.3);
VertexBuilder<String> v4 = builder.addVertex("vertex 4").setProperty("double-prop", 4.56789);

builder.addEdge(v1, v2).setProperty("edge-prop", "edge_prop_1_2").setLabel("label");
builder.addEdge(v2, v3).setProperty("edge-prop", "edge_prop_2_3").setLabel("label");
builder.addEdge(v2, v4).setProperty("edge-prop", "edge_prop_2_4").setLabel("label");
builder.addEdge(v3, v4).setProperty("edge-prop", "edge_prop_3_4").setLabel("label");
builder.addEdge(v4, v2).setProperty("edge-prop", "edge_prop_4_2").setLabel("label");

PgxGraph graph = builder.build();
from pypgx import get_session

session = get_session(session_name="example")
builder = session.create_graph_builder()

v1 = builder.add_vertex("vertex 1").set_property("double-prop", 0.1)
v2 = builder.add_vertex("vertex 2").set_property("double-prop", 2.0)
v3 = builder.add_vertex("vertex 3").set_property("double-prop", 0.3)
v4 = builder.add_vertex("vertex 4").set_property("double-prop", 4.56789)

builder.add_edge(v1, v2)
builder.add_edge(v2, v3)
builder.add_edge(v2, v4)
builder.add_edge(v3, v4)
builder.add_edge(v4, v2)

graph = builder.build()

Use GraphBuilder with Implicit IDs

The GraphBuilder supports an AUTO_GENERATED generation strategy that allows to omit the edge / vertex IDs. In this generation strategy, PGX will automatically assign IDs to the entities being added to the changeset. PgxSession supports createGraphBuilder(IdGenerationStrategy vertexIdGenerationStrategy, IdGenerationStrategy edgeIdGenerationStrategy) and createGraphBuilder(IdType idType, IdGenerationStrategy vertexIdGenerationStrategy, IdGenerationStrategy edgeIdGenerationStrategy) to specify the IdGenerationStrategy The following example illustrates the GraphBuilder by creating a graph with three vertices and three edges.

var builder = session.createGraphBuilder(IdGenerationStrategy.AUTO_GENERATED, IdGenerationStrategy.AUTO_GENERATED)
var v1 = builder.addVertex()
var v2 = builder.addVertex()
var v3 = builder.addVertex()
builder.addEdge(v1, v2)
builder.addEdge(v1, v3)
builder.addEdge(v3, v2)


var graph = builder.build()
import oracle.pgx.api.*;

PgxSession session = Pgx.createSession("example");
GraphBuilder<Integer> builder = session.createGraphBuilder(IdGenerationStrategy.AUTO_GENERATED, IdGenerationStrategy.AUTO_GENERATED);

VertexBuilder<Integer> v1 = builder.addVertex()
VertexBuilder<Integer> v2 = builder.addVertex()
VertexBuilder<Integer> v3 = builder.addVertex()
builder.addEdge(v1, v2)
builder.addEdge(v1, v3)
builder.addEdge(v3, v2)

PgxGraph graph = builder.build();
from pypgx import get_session

session = get_session(session_name="example")
builder = session.create_graph_builder(id_type='string')

v1 = builder.add_vertex()
v2 = builder.add_vertex()
v3 = builder.add_vertex()

builder.add_edge(v1, v2)
builder.add_edge(v1, v3)
builder.add_edge(v3, v2)

graph = builder.build()

Please see the Graph Builder API reference for detailed information on the graph builder.