8 グラフ・サーバー(PGX)へのPGビューのロード
プロパティ・グラフ・ビュー(PGビュー)をグラフ・サーバー(PGX)にロードするには、いくつかの方法があります。
- readGraphByName APIを使用したPGビューのロード
プロパティ・グラフ・ビュー(PGビュー)からグラフ・サーバー(PGX)にグラフを名前でロードできます。 - JSON構成ファイルを使用したグラフのロード
プロパティ・グラフ・ビューをグラフ・サーバー(PGX)にロードするために、ロードするグラフのメタデータが含まれるグラフ構成ファイルを作成できます。 - グラフ構成オブジェクトの定義によるグラフのロード
グラフをOracle Databaseからロードするには、まずGraphConfigBuilder
クラスを使用してグラフ構成オブジェクトを定義してから、グラフをグラフ・サーバー(PGX)に読み込みます。 - プロパティ・グラフ・ビューからのサブグラフのロード
プロパティ・グラフ・ビューからサブグラフを作成し、グラフ・サーバー(PGX)のメモリーにロードできます。
親トピック: プロパティ・グラフ・ビュー
8.1 readGraphByName APIを使用したPGビューのロード
プロパティ・グラフ・ビュー(PGビュー)からグラフ・サーバー(PGX)にグラフを名前でロードできます。
PgxSession#readGraphByName
APIを使用して、PGビューからグラフをロードできます。
readGraphByName(String schemaName, String graphName, GraphSource source, ReadGraphOption options)
次の表に、メソッドで使用される引数を示します:
表8-1 readGraphByName
メソッドのパラメータ
パラメータ | 説明 | オプション |
---|---|---|
schemaName |
スキーマの所有者 | はい |
graphName |
PGビューの名前 | いいえ |
source |
グラフのソース形式(GraphSource.PG_VIEW )
|
いいえ |
options |
グラフ最適化オプションを表します | はい |
readGraphByName()
メソッドは、PGビューのメタデータ表を読み取り、グラフをロードするためのグラフ構成を内部的に生成します。このAPIを使用するには、PGX_SESSION_NEW_GRAPH
権限が必要です。
たとえば、次のように、プロパティ・グラフ・ビューからグラフをロードできます。
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)
- readGraphByName APIのオプションの指定
readGraphByName
APIを使用してプロパティ・グラフ・ビュー(PGビュー)をロードする場合は、グラフ最適化オプションまたはOnMissingVertexOption
、あるいはその両方を指定できます。 - readGraphByName APIへのスキーマ名の指定
readGraphByName
APIを使用してプロパティ・グラフ・ビュー(PGビュー)をロードするときにスキーマ名を指定できます。
親トピック: グラフ・サーバー(PGX)へのPGビューのロード
8.1.1 readGraphByName
APIのオプションの指定
readGraphByName
APIを使用してプロパティ・グラフ・ビュー(PGビュー)をロードする場合は、グラフ最適化オプションまたはOnMissingVertexOption
、あるいはその両方を指定できます。
PGビューを名前でロードする際、ReadGraphOptionインタフェースでは追加のoptions
パラメータがサポートされます。
次の各項では、ReadGraphOption
インタフェースでサポートされている様々なオプションについて説明します。
グラフ最適化オプションの使用
PGビューを名前でロードする際の読取りまたは更新のパフォーマンスを最適化するには、次のいずれかのoptions
を使用します。
ReadGraphOption.optimizeFor(GraphOptimizedFor.READ)
: ロードされるグラフをREAD用に最適化することを指定します。ReadGraphOption.optimizeFor(GraphOptimizedFor.UPDATES)
: ロードされるグラフをUPDATE用に最適化することを指定します。ReadGraphOption.synchronizable()
: ロードされるグラフが同期できることを指定します。
次の点に注意してください。
-
synchronizable()
オプションは、UPDATE
およびREAD
と組み合せて使用できます。ただし、UPDATE
オプションとREAD
オプションは同時に使用できません。 SYNCHRONIZABLE
オプションのPGビューをロードする場合は、頂点キーとエッジ・キーが数値であり、コンポジットではないことを確認します。
次の例では、READ
およびSYNCHRONIZABLE
オプションのPGビューをロードします:
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());
OnMissingVertex
オプションの使用
エッジのソース頂点または宛先頂点のいずれか、あるいはその両方が欠落している場合は、頂点が欠落しているエッジを処理するための動作を指定するOnMissingVertexOption
を使用できます。このオプションでは、次の値がサポートされています。
ReadGraphOption.onMissingVertex(OnMissingVertex.ERROR)
: これはデフォルト・オプションで、頂点が欠落しているエッジに対してエラーをスローする必要があることを指定します。ReadGraphOption.onMissingVertex(OnMissingVertex.IGNORE_EDGE)
: 欠落した頂点のエッジを無視する必要があることを指定します。ReadGraphOption.onMissingVertex(OnMissingVertex.IGNORE_EDGE_LOG)
: 欠落した頂点のエッジを無視し、無視されたすべてのエッジをログに記録する必要があることを指定します。ReadGraphOption.onMissingVertex(OnMissingVertex.IGNORE_EDGE_LOG_ONCE)
: 欠落した頂点のエッジを無視し、最初の無視されたエッジのみをログに記録する必要があることを指定します。
次の例では、頂点が欠落しているエッジを無視し、最初の無視されたエッジのみをログに記録することによって、PGビューをロードします。ログを表示するには、/etc/oracle/graph/logback.xml
のデフォルトのLogback構成ファイルと、/etc/oracle/graph/logback-server.xml
のグラフ・サーバー(PGX)ロガー構成ファイルを更新して、DEBUGログを記録する必要があります。そのようにすると、無視されたエッジを/var/opt/log/pgx-server.log
ファイルで確認できます。
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));
8.1.2 readGraphByName APIへのスキーマ名の指定
readGraphByName
APIを使用してプロパティ・グラフ・ビュー(PGビュー)をロードするときにスキーマ名を指定できます。
この機能を使用すると、別のユーザー・スキーマからグラフ・サーバー(PGX)にPGビューをロードできます。ただし、別のスキーマからPGビューをロードする場合は、基礎となるすべてのメタデータおよびデータ表に対するREAD
権限を持っていることを確認してください。
次の例では、GRAPHUSER
スキーマからPGビューをロードします:
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);
8.2 JSON構成ファイルを使用したグラフのロード
プロパティ・グラフ・ビューをグラフ・サーバー(PGX)にロードするために、ロードするグラフのメタデータが含まれるグラフ構成ファイルを作成できます。
JSON構成ファイルのサンプルを次に示します:
{
"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"
}
]
}
]
}
前述の構成では、Javaキーストアの別名を使用して、キーストア・ファイルに格納されているデータベース・パスワードを参照します。詳細は、「キーストアへのデータベース・パスワードの格納」を参照してください。
また、エッジ・プロパティAMOUNT
の名前もTXN_AMT
に変更されます。これは、グラフをグラフ・サーバー(PGX)にロードするときに、必要に応じて頂点プロパティまたはエッジ・プロパティの名前を、データベースの基礎となる列の名前とは異なる名前に変更できることを意味します。
関連項目:
- グラフのロード時のPARALLELヒントの構成
- グラフ構成のオプションの詳細は、「グラフ構成のオプション」を参照してください。
これで、次に示すように、グラフをグラフサーバーに読み込むことができます。
./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);
8.2.1 グラフのロード時のPARALLELヒントの構成
基礎となるSQL問合せで使用されるGraphConfigフィールドPARALLEL_HINT_DEGREE
を使用して特定のパラレル・ヒント値を構成することで、グラフ・ロードのパフォーマンスを最適化することもできます。これは、JSON構成ファイルを使用するかGraphConfigBuilder
APIを介して、グラフをロードするときに適用できます。
次の表に、指定されたPARALLEL_HINT_DEGREE
値に基づいて内部問合せがどのように構成されるかを示します。
表8-2 PARALLEL_HINT_DEGREEの値
PARALLEL_HINT_DEGREE の値
|
SQL文で使用されるパラレル・ヒント |
---|---|
正の整数(n )
|
指定されたn 度を使用します。
|
0 (ゼロ) | プレーン・ヒントを使用します。
|
負の整数
(デフォルト値: |
PARALLELヒントはありません:
|
関連項目:
- パラレル・ヒント構成の使用例は、「JSON構成ファイルを使用したグラフのロード」を参照してください。
- パラレル・ヒント構成の使用例は、「グラフ構成オブジェクトの定義によるグラフのロード」を参照してください。
親トピック: JSON構成ファイルを使用したグラフのロード
8.3 グラフ構成オブジェクトの定義によるグラフのロード
グラフをOracle Databaseからロードするには、まずGraphConfigBuilder
クラスを使用してグラフ構成オブジェクトを定義してから、グラフをグラフ・サーバー(PGX)に読み込みます。
次の例では、データベースで<database user>/<database password>として認証してプロパティ・グラフ・ビューをメモリーにロードします。
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);
親トピック: グラフ・サーバー(PGX)へのPGビューのロード
8.4 プロパティ・グラフ・ビューからのサブグラフのロード
プロパティ・グラフ・ビューからサブグラフを作成し、グラフ・サーバー(PGX)のメモリーにロードできます。
グラフ全体をメモリーにロードするかわりに、サブグラフをロードできます。これにより、消費されるメモリーが少なくなります。
次の各項では、サブグラフのロードおよび拡張について詳しく説明します。
- PGQLベースのサブグラフのロード
PgViewSubgraphReader#fromPgView
APIを使用し、一連のPGQL問合せを使用してプロパティ・グラフ・ビュー(PGビュー)からインメモリー・サブグラフを作成できます。 - 準備済PGQL問合せ
プロパティ・グラフ・ビューからサブグラフをロードするときに、準備済問合せを使用することもできます。 - データベース接続資格証明の指定
現在のユーザーのデフォルト資格証明を使用するかわりに、PgViewSubgraphReader#fromPgView
APIを使用してデータベース接続資格証明を指定できます。 - サブグラフの動的な拡張
インメモリー・サブグラフを拡張するには、別のサブグラフをメモリーにロードし、現在のインメモリー・サブグラフとマージします。
親トピック: グラフ・サーバー(PGX)へのPGビューのロード
8.4.1 PGQLベースのサブグラフのロード
PgViewSubgraphReader#fromPgView
APIを使用し、一連のPGQL問合せを使用してプロパティ・グラフ・ビュー(PGビュー)からインメモリー・サブグラフを作成できます。
これらのPGQL問合せは、サブグラフにロードされる頂点およびエッジを定義します。複数のPGQL問合せを使用することもでき、結果の出力グラフはサブグラフを結合したものであり、それぞれが各PGQL問合せによって別々にロードされます。
ノート:
- 非コンポジットの頂点およびエッジ・キーのみがサポートされています。
- 数値エッジ・キーのみがサポートされています。
- プロパティ・グラフ・ビューからのサブグラフのロードでは、
GROUP BY
句またはORDER BY
句を指定したPGQL問合せはサポートされていません。
次の例では、複数のPGQL問合せを使用してPGビューからサブグラフを作成します。
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)
グラフ・ビジュアライゼーション・ツールを使用した前述のPGQL問合せの出力を次に示します。
カスタム名によるサブグラフのロード
デフォルトでは、新しいサブグラフはPGビュー・グラフと同じ名前で作成されます。あるいは、カスタム名でサブグラフをロードする場合は、次のようにサブグラフ名を構成できます。
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)
スキーマ名の明示的な指定によるサブグラフのロード
別のスキーマからPGビューを読み取ることでサブグラフをロードする場合は、さらにPgViewSubgraphReader#fromPgView
APIの引数としてスキーマ名を指定できます。また、PGビューの基礎となるすべてのメタデータおよびデータ表に対するREAD
権限を持っていることも確認する必要があります。
たとえば:
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")
親トピック: プロパティ・グラフ・ビューからのサブグラフのロード
8.4.2 準備済PGQL問合せ
プロパティ・グラフ・ビューからサブグラフをロードするときに、準備済問合せを使用することもできます。
準備済PGQL問合せを使用してバインド変数を渡すことができます。PreparedPgViewPgqlQuery#preparedPgqlQuery
メソッドは、サブグラフをロードするために実行される問合せのリストに準備済問合せを追加します。PreparedPgViewPgqlQuery
APIは、変数のバインディングを設定し、サブグラフのロードを続行します。
たとえば:
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)
親トピック: プロパティ・グラフ・ビューからのサブグラフのロード
8.4.3 データベース接続資格証明の指定
現在のユーザーのデフォルト資格証明を使用するかわりに、PgViewSubgraphReader#fromPgView
APIを使用してデータベース接続資格証明を指定できます。
次の例は、デフォルト以外のデータベース接続設定のサブグラフのロードを示しています。
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();
親トピック: プロパティ・グラフ・ビューからのサブグラフのロード
8.4.4 サブグラフの動的な拡張
インメモリー・サブグラフを拡張するには、別のサブグラフをメモリーにロードし、現在のインメモリー・サブグラフとマージします。
PgxGraph.expandGraph()
メソッドを使用すると、サブグラフを拡張できます。2つのグラフをマージする際、次のことが適用されます。
- 両方のグラフに別々のプロバイダ・セットを含めることができます。
- グラフには、他のグラフと同じプロバイダをいくつか含めることができます。この場合、次のようになります:
- 同じ名前のプロバイダには、同じラベルが必要です。
- マージ対象のグラフには、ベース・グラフと同じまたは共通のプロパティのサブセットが必要です。ただし、いずれか一方のグラフのプロパティ数が多くなる可能性があります。
次の例に、「PGQLベースのサブグラフのロード」で作成したサブグラフの拡張を示します。
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)
グラフ・ビジュアライゼーション・ツールを使用した前述のPGQL問合せの出力を次に示します。これで、サブグラフは拡張され、サブグラフにすでに存在していたPERSONS(1)
に加えて、PERSONS(2)
のfriendOf
関係が含まれるようになります。
スキーマ名の明示的な指定によるサブグラフの拡張
グラフを拡張するときに、別のスキーマからPGビューを読み取ることで、別のサブグラフをロードできます。このためには、PgqlViewGraphExpander#fromPgView
APIの引数としてスキーマ名を指定する必要があります。また、PGビューの基礎となるすべてのメタデータおよびデータ表に対するREAD
権限を持っていることも確認する必要があります。
たとえば:
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)
マージ戦略の使用
グラフの拡張時に、新しいグラフ・データにある頂点およびエッジの一部がすでにベース・グラフにロードされている場合があります。このような場合、頂点およびエッジのプロパティ値が、ベース・グラフとマージ対象となる新しいグラフの両方にあるすべての頂点およびエッジで異なる場合、次のことが適用されます。
- マージ戦略が
KEEP_CURRENT_VALUES
の場合、新しいグラフからの頂点およびエッジのプロパティ値は無視されます。 - マージ戦略が
UPDATE_WITH_NEW_VALUES
の場合、頂点およびエッジのプロパティ値は新しいグラフで検出された値で更新されます。
たとえば:
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();
親トピック: プロパティ・グラフ・ビューからのサブグラフのロード