8 Loading a PG View into the Graph Server (PGX)
There are several ways to load a property graph view (PG View) into the graph server (PGX).
- Loading a PG View Using the readGraphByName API
You can load a graph into the graph server (PGX) from a property graph view (PG View) by name. - Loading a Graph Using a JSON Configuration File
In order to load a property graph view into the graph server (PGX), you can create a graph configuration file, which contains the metadata of the graph to be loaded. - Loading a Graph by Defining a Graph Configuration Object
You can load a graph from Oracle Database by first defining the graph configuration object using theGraphConfigBuilder
class and then reading the graph into the graph server (PGX). - Loading a Subgraph from Property Graph Views
You can create a subgraph from a property graph view and load it into memory in the graph server (PGX).
Parent topic: Property Graph Views
8.1 Loading a PG View Using the readGraphByName API
You can load a graph into the graph server (PGX) from a property graph view (PG View) by name.
You can use the PgxSession#readGraphByName
API to load a graph from
a PG View:
readGraphByName(String schemaName, String graphName,
GraphSource source, ReadGraphOption options)
The arguments used in the method are described in the following table:
Table 8-1 Parameters for
the readGraphByName
method
Parameter | Description | Optional |
---|---|---|
schemaName |
Schema owner | Yes |
graphName |
Name of the PG View | No |
source |
Source format for the graph
(GraphSource.PG_VIEW )
|
No |
options |
Represents the graph optimization options | Yes |
The readGraphByName()
method reads the PG View
metadata tables and internally generates the graph configuration to load the
graph. You must have PGX_SESSION_NEW_GRAPH
permission to
use this API.
For example you can load the graph from a property graph view as shown:
opg4j> var graph = session.readGraphByName("BANKDATAVIEW", GraphSource.PG_VIEW)
$12 ==> PgxGraph[name=bankdataview,N=1000,E=5001,created=1625730942294]
PgxGraph graph = session.readGraphByName("BANKDATAVIEW", GraphSource.PG_VIEW);
Graph: PgxGraph[name=bankdataview,N=1000,E=5001,created=1625732149262]
>>> graph = session.read_graph_by_name('BANKDATAVIEW', 'pg_view')
>>> graph
PgxGraph(name: bankdataview, v: 1000, e: 5001, directed: True, memory(Mb): 0)
- Specifying Options for the readGraphByName API
You can specify graph optimization options,OnMissingVertexOption
or both when using thereadGraphByName
API for loading a property graph view (PG View). - Specifying the Schema Name for the readGraphByName API
You can specify the schema name when using thereadGraphByName
API for loading a property graph view (PG View).
Parent topic: Loading a PG View into the Graph Server (PGX)
8.1.1 Specifying Options for the
readGraphByName
API
You can specify graph optimization options,
OnMissingVertexOption
or both when using the readGraphByName
API for loading a property graph view (PG View).
The ReadGraphOption interface supports an
additional options
parameter when loading a PG View by name.
The following sections explain the various options supported by the
ReadGraphOption
interface.
Using the Graph Optimization Options
You can optimize the read or update performance
when loading a PG View by name by using one of the following options
:
ReadGraphOption.optimizeFor(GraphOptimizedFor.READ)
: Specifies that the loaded graph is optimized for READ.ReadGraphOption.optimizeFor(GraphOptimizedFor.UPDATES)
: Specifies that the loaded graph is optimized for UPDATE.ReadGraphOption.synchronizable()
: Specifies that the loaded graph can be synchronized.
It is important to note the following:
-
synchronizable()
option can be used in combination withUPDATE
andREAD
. However, theUPDATE
andREAD
options cannot be used at the same time. - If you are loading a PG View for
SYNCHRONIZABLE
option, then ensure that the vertex and edge keys are numeric and non-composite.
The following example loads a PG View for
READ
and SYNCHRONIZABLE
options:
opg4j> var graph = session.readGraphByName("BANK_GRAPH_VIEW", GraphSource.PG_VIEW,
...> ReadGraphOption.optimizeFor(GraphOptimizedFor.READ),
...> ReadGraphOption.synchronizable())
graph ==> PgxGraph[name=BANK_GRAPH_VIEW_2,N=1000,E=5001,created=1648457198462]
PgxGraph graph = session.readGraphByName("BANKDATAVIEW", GraphSource.PG_VIEW, "BANK_GRAPH_VIEW", GraphSource.PG_VIEW,
ReadGraphOption.optimizeFor(GraphOptimizedFor.READ),
ReadGraphOption.synchronizable());
Using the
OnMissingVertex
Options
If either the source or destination vertex or both are missing for an edge,
then you can use the OnMissingVertexOption
which specifies the behavior for
handling the edge with the missing vertex. The following values are supported for this
option:
ReadGraphOption.onMissingVertex(OnMissingVertex.ERROR)
: This is the default option and this specifies that an error must be thrown for edges with missing vertices.ReadGraphOption.onMissingVertex(OnMissingVertex.IGNORE_EDGE)
: Specifies that the edge for a missing vertex must be ignored.ReadGraphOption.onMissingVertex(OnMissingVertex.IGNORE_EDGE_LOG)
: Specifies that the edge for a missing vertex must be ignored and all ignored edges must be logged.ReadGraphOption.onMissingVertex(OnMissingVertex.IGNORE_EDGE_LOG_ONCE)
: Specifies that the edge for a missing vertex must be ignored and only the first ignored edge must be logged.
The following example loads the PG View by ignoring the edges with missing
vertices and logging only the first ignored edge. Note, to view the logs, you must update
the default Logback configuration file in /etc/oracle/graph/logback.xml
and
the graph server (PGX) logger configuration file in
/etc/oracle/graph/logback-server.xml
to log the DEBUG logs. You can then
view the ignored edges in /var/opt/log/pgx-server.log
file.
opg4j> session.readGraphByName("REGIONS", GraphSource.PG_VIEW,
...> ReadGraphOption.onMissingVertex(OnMissingVertex.IGNORE_EDGE_LOG_ONCE))
$7 ==> PgxGraph[name=REGIONVIEW_3,N=27,E=18,created=1655903219910]
PgxGraph graph = session.readGraphByName("REGIONS", GraphSource.PG_VIEW, ReadGraphOption.onMissingVertex(OnMissingVertex.IGNORE_EDGE_LOG_ONCE));
Parent topic: Loading a PG View Using the readGraphByName API
8.1.2 Specifying the Schema Name for the readGraphByName API
You can specify the schema name when using the
readGraphByName
API for loading a property graph view (PG View).
This feature allows you load a PG View from
another user schema into the graph server (PGX). However, ensure that you have
READ
permission on all the underlying metadata and data tables when
loading a PG View from another schema.
The following example loads a PG View from the
GRAPHUSER
schema:
opg4j> var graph = session.readGraphByName("GRAPHUSER", "FRIENDS", GraphSource.PG_VIEW)
graph ==> PgxGraph[name=FRIENDS,N=6,E=4,created=1672743474212]
PgxGraph graph = session.readGraphByName("GRAPHUSER", "FRIENDS", GraphSource.PG_VIEW);
Parent topic: Loading a PG View Using the readGraphByName API
8.2 Loading a Graph Using a JSON Configuration File
In order to load a property graph view into the graph server (PGX), you can create a graph configuration file, which contains the metadata of the graph to be loaded.
The following shows a sample JSON configuration file:
{
"name": "BANK_GRAPH",
"source_name": "BANK_GRAPH",
"source_type": "pg_view",
"jdbc_url":"jdbc:oracle:thin:@localhost:1521/orclpdb",
"username":"graphuser",
"keystore_alias":"database1",
"vertex_providers":[
{
"name":"Accounts",
"format":"rdbms",
"database_table_name":"BANK_ACCOUNTS",
"key_column":"ID",
"key_type": "integer",
"parallel_hint_degree": 3,
"props":[
{
"name":"ID",
"type":"integer"
},
{
"name":"NAME",
"type":"string"
}
]
}
],
"edge_providers":[
{
"name":"Transfers",
"format":"rdbms",
"database_table_name":"BANK_TXNS",
"key_column":"ID",
"parallel_hint_degree": 3,
"source_column":"FROM_ACCT_ID",
"destination_column":"TO_ACCT_ID",
"source_vertex_provider":"Accounts",
"destination_vertex_provider":"Accounts",
"props":[
{
"name":"FROM_ACCT_ID",
"type":"integer"
},
{
"name":"TXN_AMOUNT",
"type":"float",
"column":"AMOUNT"
},
{
"name":"DESCRIPTION",
"type":"string"
},
{
"name":"TO_ACCT_ID",
"type":"integer"
}
]
}
]
}
The preceding configuration uses a Java keystore alias to reference the database password that is stored in a keystore file. See Store the Database Password in a Keystore for more information.
Also, the edge property AMOUNT
is renamed to
TXN_AMT
. This implies that when loading a graph into the graph
server (PGX), you can optionally rename vertex or edge properties to have different
names other than the names of the underlying columns in the database.
See Also:
- Configuring PARALLEL Hint when Loading a Graph
- Graph Configuration Options for more details on the graph configuration options.
You can now read the graph into the graph server as shown:
./bin/opg4j --secret_store /etc/oracle/graph/keystore.p12
enter password for keystore /etc/oracle/graph/keystore.p12:
For an introduction type: /help intro
Oracle Graph Server Shell 23.1.0
Variables instance, session, and analyst ready to use
opg4j> var g = session.readGraphWithProperties("<path_to_json_configuration>")
g ==> PgxGraph[name=BANK_GRAPH_NEW,N=999,E=4993,created=1675960224397]
ServerInstance instance = GraphServer.getInstance("https://localhost:7007", <username>, <password>.toCharArray());
PgxSession session = instance.createSession("my-session");
String keystorePath = "/etc/oracle/graph/keystore.p12";
char[] keystorePassword = "<keystore_password>".toCharArray();
session.registerKeystore(keystorePath, keystorePassword);
PgxGraph g = session.readGraphWithProperties("<path_to_json_configuration>");
System.out.println("Graph: " + g);
Parent topic: Loading a PG View into the Graph Server (PGX)
8.2.1 Configuring PARALLEL Hint when Loading a Graph
You can also optimize the graph loading performance by configuring a
specific parallel hint value using the GraphConfig field,
PARALLEL_HINT_DEGREE
, which will be used by the underlying SQL
queries. This can be applied when loading a graph using a JSON configuration file or
through the GraphConfigBuilder
API.
The following table describes how the internal queries are configured based
on the specified PARALLEL_HINT_DEGREE
values.
Table 8-2 PARALLEL_HINT_DEGREE values
PARALLEL_HINT_DEGREE Value
|
Parallel hint used in the SQL Statement |
---|---|
Positive integer(n )
|
Uses the given n degree:
|
Zero | Uses a plain hint:
|
Negative integer
(Default value:
|
No PARALLEL hint:
|
See Also:
- Loading a Graph Using a JSON Configuration File for an example using parallel hint configuration.
- Loading a Graph by Defining a Graph Configuration Object for an example using parallel hint configuration.
Parent topic: Loading a Graph Using a JSON Configuration File
8.3 Loading a Graph by Defining a Graph Configuration Object
You can load a graph from Oracle Database by first defining the graph configuration
object using the GraphConfigBuilder
class and then reading the graph into
the graph server (PGX).
The following example loads a property graph view into memory, authenticating as <database user>/<database password> with the database:
opg4j> var vertexConfig = new RdbmsEntityProviderConfigBuilder().
...> setName("Account").
...> setKeyColumn("ID").
...> setParallelHintDegree(3).
...> setDatabaseTableName("BANK_ACCOUNTS").
...> addProperty("ID", PropertyType.INTEGER).
...> build()
opg4j> var edgeConfig = new RdbmsEntityProviderConfigBuilder().
...> setName("Transfer").
...> setKeyColumn("TXN_ID").
...> setSourceColumn("FROM_ACCT_ID").
...> setDestinationColumn("TO_ACCT_ID").
...> setSourceVertexProvider("Account").
...> setDestinationVertexProvider("Account").
...> setParallelHintDegree(3).
...> createKeyMapping(true).
...> setDatabaseTableName("BANK_TXNS").
...> addProperty("FROM_ACCT_ID", PropertyType.INTEGER).
...> addProperty("TO_ACCT_ID", PropertyType.INTEGER).
...> addProperty("AMOUNT", PropertyType.FLOAT).
...> build()
opg4j> var cfg = GraphConfigBuilder.forPartitioned().
...> setJdbcUrl("jdbc:oracle:thin:@localhost:1521/orclpdb").
...> setUsername("graphuser").
...> setPassword("<password>").
...> setName("bank_graph").
...> setSourceName("bank_graph").
...> setSourceType(SourceType.PG_VIEW).
...> setVertexIdType(IdType.INTEGER).
...> addVertexProvider(vertexConfig).
...> addEdgeProvider(edgeConfig).
...> build()
opg4j> var g = session.readGraphWithProperties(cfg)
g ==> PgxGraph[name=bank_graph,N=999,E=4993,created=1676806306348]
// Build the vertex provider
RdbmsEntityProviderConfig vertexConfig = new RdbmsEntityProviderConfigBuilder()
.setName("Account")
.setKeyColumn("ID")
.setParallelHintDegree(3)
.setDatabaseTableName("BANK_ACCOUNTS")
.addProperty("ID", PropertyType.INTEGER)
.build();
// Build the edge provider
RdbmsEntityProviderConfig edgeConfig = new RdbmsEntityProviderConfigBuilder()
.setName("Transfer")
.setKeyColumn("TXN_ID")
.setSourceColumn("FROM_ACCT_ID")
.setDestinationColumn("TO_ACCT_ID")
.setSourceVertexProvider("Account")
.setDestinationVertexProvider("Account")
.setParallelHintDegree(3)
.createKeyMapping(true)
.setDatabaseTableName("BANK_TXNS")
.addProperty("FROM_ACCT_ID", PropertyType.INTEGER)
.addProperty("TO_ACCT_ID", PropertyType.INTEGER)
.addProperty("AMOUNT", PropertyType.FLOAT)
.build();
// Build the graph
GraphConfig cfg = GraphConfigBuilder.forPartitioned()
.setJdbcUrl("jdbc:oracle:thin:@localhost:1521/orclpdb")
.setUsername("graphuser")
.setPassword("<password>")
.setName("bank_graph")
.setSourceName("bank_graph")
.setSourceType(SourceType.PG_VIEW)
.setVertexIdType(IdType.INTEGER)
.addVertexProvider(vertexConfig)
.addEdgeProvider(edgeConfig)
.build();
PgxGraph g = session.readGraphWithProperties(cfg);
Parent topic: Loading a PG View into the Graph Server (PGX)
8.4 Loading a Subgraph from Property Graph Views
You can create a subgraph from a property graph view and load it into memory in the graph server (PGX).
Instead of loading a full graph into memory, you can load a subgraph. This would consume less memory.
The following sections explain in detail on loading and expanding of subgraphs:
- PGQL Based Subgraph Loading
You can use thePgViewSubgraphReader#fromPgView
API to create an in-memory subgraph from a property graph view (PG View) using a set of PGQL queries. - Prepared PGQL Queries
You can also use prepared queries when loading a subgraph from a property graph view. - Providing Database Connection Credentials
You can specify the database connection credentials with thePgViewSubgraphReader#fromPgView
API instead of using the default credentials of the current user. - Dynamically Expanding a Subgraph
You can expand an in-memory subgraph by loading another subgraph into memory and merging it with the current in-memory subgraph.
Parent topic: Loading a PG View into the Graph Server (PGX)
8.4.1 PGQL Based Subgraph Loading
You can use the PgViewSubgraphReader#fromPgView
API to
create an in-memory subgraph from a property graph view (PG View) using a set of
PGQL queries.
These PGQL queries define the vertices and edges that are to be loaded into the subgraph. You can also use multiple PGQL queries and the resulting output graph is a union of the subgraphs, each being loaded independently by each PGQL query.
Note:
- Only non-composite vertex and edge keys are supported.
- Only numeric edge keys are supported.
- PGQL queries with
GROUP BY
orORDER BY
clauses are not supported for loading of subgraphs from a property graph view.
The following example creates a subgraph from a PG View using multiple PGQL queries:
opg4j> var graph = session.readSubgraph().
...> fromPgView("FRIENDS").
...> queryPgql("MATCH (v1:Person)-[e:FRIENDOF]->(v2:Person) WHERE id(v1) = 'PERSONS(1)'").
...> queryPgql("MATCH (v:Person) WHERE id(v) = 'PERSONS(2)'").
...> load()
graph ==> PgxGraph[name=FRIENDS,N=3,E=1,created=1646726883194]
PgxGraph graph = session.readSubgraph()
.fromPgView("FRIENDS")
.queryPgql("MATCH (v1:Person)-[e:FRIENDOF]->(v2:Person) WHERE id(v1) = 'PERSONS(1)'")
.queryPgql("MATCH (v:Person) WHERE id(v) = 'PERSONS(2)'")
.load();
>>> graph = session.read_subgraph_from_pg_view("FRIENDS", ["MATCH (v1:Person)-[e:FRIENDOF]->(v2:Person) WHERE id(v1) = 'PERSONS(1)'",
... "MATCH (v:Person) WHERE id(v) = 'PERSONS(2)'"])
>>> graph
PgxGraph(name: FRIENDS, v: 3, e: 1, directed: True, memory(Mb): 0)
The following displays the output for the preceding PGQL query using the graph visualization tool.
Loading Subgraphs with Custom Names
By default, the new subgraph gets created with the same name as the PG View graph. Alternatively, if you want to load a subgraph with a custom name, then you can configure the subgraph name as shown:
opg4j> var graph = session.readSubgraph().
...> fromPgView("FRIENDS").
...> queryPgql("MATCH (v1:Person)-[e:FRIENDOF]->(v2:Person) WHERE id(v1) = 'PERSONS(1)'").
...> queryPgql("MATCH (v:Person) WHERE id(v) = 'PERSONS(2)'").
...> load("friends_network")
graph ==> PgxGraph[name=friends_network,N=3,E=1,created=1664458398090]
PgxGraph graph = session.readSubgraph()
.fromPgView("FRIENDS")
.queryPgql("MATCH (v1:Person)-[e:FRIENDOF]->(v2:Person) WHERE id(v1) = 'PERSONS(1)'")
.queryPgql("MATCH (v:Person) WHERE id(v) = 'PERSONS(2)'")
.load("friends_network");
>>> graph = session.read_subgraph_from_pg_view("FRIENDS",
... ["MATCH (v1:Person)-[e:FRIENDOF]->(v2:Person) WHERE id(v1) = 'PERSONS(1)'",
... "MATCH (v:Person) WHERE id(v) = 'PERSONS(2)'"],
... graph_name="friends_network")
>>> graph
PgxGraph(name: friends_network, v: 3, e: 1, directed: True, memory(Mb): 0)
Loading a Subgraph by Explicitly Specifying the Schema Name
If you want to load a subgraph by reading a PG View from
another schema, you can additionally provide the schema name as an
argument to the PgViewSubgraphReader#fromPgView
API
. You must also ensure that you have READ
permission on all the underlying metadata and data tables for the PG
View.
For example:
opg4j> var graph = session.readSubgraph()
...> .fromPgView("GRAPHUSER", "FRIENDS")
...> .queryPgql("MATCH (v:Person) WHERE id(v) = 'PERSONS(2)'")
...> .load()
graph ==> PgxGraph[name=FRIENDS,N=1,E=0,created=1672743755511]
PgxGraph graph = session.readSubgraph()
.fromPgView("GRAPHUSER", "FRIENDS")
.queryPgql("MATCH (v:Person) WHERE id(v) = 'PERSONS(2)'")
.load();
>>> graph = session.read_subgraph_from_pg_view("FRIENDS",
... ["MATCH (v:Person) WHERE id(v) = 'PERSONS(2)'"],
... schema="GRAPHUSER")
Parent topic: Loading a Subgraph from Property Graph Views
8.4.2 Prepared PGQL Queries
You can also use prepared queries when loading a subgraph from a property graph view.
You can pass bind variables using prepared PGQL queries. The
PreparedPgViewPgqlQuery#preparedPgqlQuery
method adds a prepared
query to a list of queries that are executed to load the subgraph. The
PreparedPgViewPgqlQuery
API sets the bindings for the variables and
continues with the loading of the subgraph.
For example:
opg4j> var pgViewSubgraphReader = session.readSubgraph().
...> fromPgView("FRIENDS")
pgViewSubgraphReader ==> oracle.pgx.api.subgraph.PgViewSubgraphReader@33bfe6d3
opg4j> var preparedPgqlQuery = pgViewSubgraphReader.preparedPgqlQuery("MATCH (v1:Person)-[e:FriendOf]->(v2:Person) WHERE id(v2)=?")
preparedPgqlQuery ==> oracle.pgx.api.subgraph.PreparedPgViewPgqlQuery@2e6b379c
opg4j> preparedPgqlQuery = preparedPgqlQuery.withStringArg(1, "PERSONS(3)")
preparedPgqlQuery ==> oracle.pgx.api.subgraph.PreparedPgViewPgqlQuery@2e6b379c
opg4j> var graph = preparedPgqlQuery.load()
graph ==> PgxGraph[name=FRIENDS_2,N=3,E=2,created=1648566047855]
import oracle.pgx.api.subgraph.*;
…
…
PgViewSubgraphReader pgViewSubgraphReader= session.readSubgraph().fromPgView("FRIENDS");
PreparedPgViewPgqlQuery preparedPgqlQuery = pgViewSubgraphReader.preparedPgqlQuery("MATCH (v1:Person)-[e:FriendOf]->(v2:Person) WHERE id(v2)=?");
preparedPgqlQuery = preparedPgqlQuery.withStringArg(1, "PERSONS(3)");
PgxGraph graph = preparedPgqlQuery.load();
>>> from pypgx.api import PreparedPgqlQuery
>>> from pypgx.api import PreparedPgqlQueryStringArgument
>>> graph = session.read_subgraph_from_pg_view("FRIENDS",
... [PreparedPgqlQuery("MATCH (v1:Person)-[e:FriendOf]->(v2:Person) WHERE id(v2)=?", [PreparedPgqlQueryStringArgument("PERSONS(3)")])])
>>> graph
PgxGraph(name: FRIENDS, v: 3, e: 2, directed: True, memory(Mb): 0)
Parent topic: Loading a Subgraph from Property Graph Views
8.4.3 Providing Database Connection Credentials
You can specify the database connection credentials with the
PgViewSubgraphReader#fromPgView
API instead of using the
default credentials of the current user.
The following example shows loading of a subgraph for non-default database connection settings:
opg4j> var graph = session.readSubgraph().
...> fromPgView("FRIENDS").
...> username("graphuser").
...> password("<password_for_graphuser>").
...> keystoreAlias("database1").
...> schema("graphuser").
...> jdbcUrl("jdbc:oracle:thin:@localhost:1521/orclpdb").
...> connections(12).
...> queryPgql("MATCH (a:Person)").
...> load()
graph ==> PgxGraph[name=FRIENDS,N=4,E=0,created=1648541234520]
PgxGraph graph = session.readSubgraph()
.fromPgView("FRIENDS")
.username("graphuser")
.password("<password_for_graphuser>")
.keystoreAlias("database1")
.schema("graphuser")
.jdbcUrl("jdbc:oracle:thin:@localhost:1521/orclpdb")
.connections(12)
.queryPgql("MATCH (a:Person)")
.load();
Parent topic: Loading a Subgraph from Property Graph Views
8.4.4 Dynamically Expanding a Subgraph
You can expand an in-memory subgraph by loading another subgraph into memory and merging it with the current in-memory subgraph.
The PgxGraph.expandGraph()
method can be used to
expand a subgraph. The following applies when merging two graphs:
- Both the graphs can have separate sets of providers.
- A graph can have some providers same as the other graph. In this
case:
- The providers with the same names must have the same labels.
- The graph being merged must have the same or a common subset of properties as the base graph. However, it is possible that either of the graphs may have more number of properties.
The following example shows the expansion of the subgraph created in PGQL Based Subgraph Loading:
opg4j> graph = graph.expandGraph().
...> withPgql().
...> fromPgView("FRIENDS").
...> queryPgql("MATCH (v1:PERSON) -[e:FRIENDOF]-> (v2:PERSON) WHERE id(v1) = 'PERSONS(2)'").
...> preparedPgqlQuery("MATCH (v:PERSON) WHERE id(v) in ?").withStringArg(1, "PERSONS(4)").
...> expand()
graph ==> PgxGraph[name=anonymous_graph_152,N=4,E=3,created=1647347092964]
graph = graph.expandGraph()
.withPgql()
.fromPgView("FRIENDS")
.queryPgql("MATCH (v1:PERSON) -[e:FRIENDOF]-> (v2:PERSON) WHERE id(v1) = 'PERSONS(2)'")
.preparedPgqlQuery("MATCH (v:PERSON) WHERE id(v) in ?").withStringArg(1, "PERSONS(4)")
.expand();
>>> from pypgx.api import PreparedPgqlQuery
>>> from pypgx.api import PreparedPgqlQueryStringArgument
>>> graph = graph.expand_with_pgql(["MATCH (v1:PERSON) -[e:FRIENDOF]-> (v2:PERSON) WHERE id(v1) = 'PERSONS(2)'",
... PreparedPgqlQuery("MATCH (v:Person) WHERE id(v)=?", [PreparedPgqlQueryStringArgument("PERSONS(4)")])],
... pg_view_name="FRIENDS")
>>> graph
PgxGraph(name: anonymous_graph_66, v: 4, e: 3, directed: True, memory(Mb): 0)
The following displays the output for the preceding PGQL
query using the graph visualization tool. The subgraph is now
expanded to include the friendOf
relationship for
PERSONS(2)
in addition to
PERSONS(1)
which was already existing in
the subgraph.
Expanding a Subgraph by Explicitly Specifying the Schema Name
When expanding a graph, you can load another subgraph by
reading a PG View from a different schema. For this, you must
provide the schema name as an argument to the
PgqlViewGraphExpander#fromPgView
API. You
must also ensure that you have READ
permission on
all the underlying metadata and data tables for the PG View.
For example:
opg4j> graph = graph.expandGraph().
...> withPgql().
...> fromPgView("GRAPHUSER", "FRIENDS").
...> queryPgql("MATCH (v:Person) WHERE id(v) = 'PERSONS(1)'").
...> expand()
graph ==> PgxGraph[name=anonymous_graph_18,N=1,E=0,created=1672848726308]
graph = graph.expandGraph()
.withPgql()
.fromPgView("GRAPHUSER", "FRIENDS")
.queryPgql("MATCH (v:Person) WHERE id(v) = 'PERSONS(1)'")
.expand();
>>> graph = graph.expand_with_pgql("MATCH (v:Person) WHERE id(v) = 'PERSONS(1)'",
... pg_view_name="FRIENDS", schema="GRAPHUSER")
>>> graph
PgxGraph(name: anonymous_graph_6, v: 2, e: 0, directed: True, memory(Mb): 0)
Using Merging Strategy
When expanding a graph, some vertices and edges that are in the new graph data may have already been loaded in the base graph. In such cases, if the vertex and edge property values differ for all vertices and edges that are both in the base graph and in the new graph to be merged, then the following applies:
- If the merging strategy is
KEEP_CURRENT_VALUES
, then the vertex and edge property values coming from the new graph are ignored. - If the merging strategy is
UPDATE_WITH_NEW_VALUES
, then the vertex and edge property values are updated with the ones found in the new graph.
For example:
opg4j> import oracle.pgx.api.expansion.PropertyMergeStrategy
opg4j> graph = graph.expandGraph().
...> withPgql().
...> fromPgView("FRIENDS").
...> queryPgql("MATCH (v1:PERSON) -[e:FRIENDOF]-> (v2:PERSON) WHERE id(v1) = 'PERSONS(2)'").
...> preparedPgqlQuery("MATCH (v:PERSON) WHERE id(v) in ?").withStringArg(1, "PERSONS(4)").
...> vertexPropertiesMergingStrategy(PropertyMergeStrategy.UPDATE_WITH_NEW_VALUES).
...> expand()
import oracle.pgx.api.expansion.PropertyMergeStrategy;
graph = graph.expandGraph()
.withPgql()
.fromPgView("FRIENDS")
.queryPgql("MATCH (v1:PERSON) -[e:FRIENDOF]-> (v2:PERSON) WHERE id(v1) = 'PERSONS(2)'")
.preparedPgqlQuery("MATCH (v:PERSON) WHERE id(v) in ?").withStringArg(1, "PERSONS(4)")
.vertexPropertiesMergingStrategy(PropertyMergeStrategy.UPDATE_WITH_NEW_VALUES)
.expand();
Parent topic: Loading a Subgraph from Property Graph Views