10.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関係が含まれるようになります。

図10-2 サブグラフの拡張

図10-2の説明が続きます
「図10-2 サブグラフの拡張」の説明

スキーマ名の明示的な指定によるサブグラフの拡張

グラフを拡張するときに、別のスキーマからPGQLプロパティ・グラフを読み取ることで、別のサブグラフをロードできます。このためには、PgqlViewGraphExpander#fromPgView APIの引数としてスキーマ名を指定する必要があります。また、PGQLプロパティ・グラフの基礎となるすべてのメタデータおよびデータ表に対する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();