11 Oracle Databaseに格納されたプロパティ・グラフ・データとのRDF統合

プロパティ・グラフ・データ・モデルが、Oracle Spatial and Graphでサポートされています。Oracle Spatial and Graphは、Oracle Databaseに格納されたプロパティ・グラフ・データのRDFビューに標準で対応しています。

11.1 プロパティ・グラフ・データとのRDF統合について

プロパティ・グラフ・データ・モデルは、グローバルにリソースを特定する概念(つまりURI)、あるいはフォーマルなセマンティクスや伴意の概念がないため、RDFデータ・モデルよりも単純です。さらに、プロパティ・グラフではプロパティ(キーと値のペア)をエッジと直接関係付けることができます。それとは対照的に、RDFでプロパティをエッジと関係付けるには、具象化、つまりクワッド・データ・モデルが必要になります(RDFトリプル)。

Oracle Spatial and Graphは、Oracle Databaseに格納されたプロパティ・グラフ・データのRDFビューに標準で対応しています。このRDFビューが、プロパティ・グラフ・データとRDFデータとの統合ポイントになります。プロパティ・グラフ・データのRDFビューは、その他のRDFビューと同じように動作します。したがって、ビューに対するSPARQL問合せの実行、およびネイティブなRDFモデルとしてのビューの生成が可能です。プロパティ・グラフのRDFビューに対するサポートは、次のコンポーネントを通じて行われます。

  • プロパティ・グラフ・データを格納するために使用されるリレーショナル・スキーマに対する組込みのR2RMLマッピング(スキーマを参照)。

  • プロパティ・グラフ・データに対する組込みのR2RMLマッピングを使用してRDFビューの作成と保守を行うPL/SQL API。

RDFでプロパティ・グラフ・データを表現する場合、主に考慮すべき点が2つあります。

  • 文法的に有効なRDF語句(URI、リテラルなど)を、プロパティ・グラフの識別子または値からどのように生成するか

  • エッジ・プロパティ(エッジに対するキーと値のペア)をどのように表現するか

Oracle Spatial and Graphでは、プロパティ・グラフ識別子からのURI生成には特定の接頭辞が使用され、プロパティの値に対してはXMLスキーマの型付きリテラルが使用されます。エッジ・プロパティのモデル化には、名前付きグラフが使用されます。

次の図に示す例は、RDFマッピングに対するプロパティ・グラフを表すものです。ここで、プロパティ・グラフ・モデルのエッジが、RDFクワッドになることに注意してください。その際、その述部はエッジ・ラベルで、名前付きグラフはエッジ識別子から作られたURIです。そしてエッジ・プロパティは、エッジに対する名前付きグラフ内で、RDFクワッドとしてモデル化されます。次の図におけるRDFグラフのTrigシリアライズを実例として示すと、次のようになります。

@PREFIX edge: <http://xmlns.oracle.com/pg/edge/> .
@PREFIX vertex: <http://xmlns.oracle.com/pg/vertex/> .
@PREFIX ep: <http://xmlns.oracle.com/pg/property/edge/> .
@PREFIX vp: <http://xmlns.oracle.com/pg/property/vertex/> .
@PREFIX label: <http://xmlns.oracle.com/pg/property/edge/label/> .

vertex:v1 vp:name "John";
          vp:age 40 .
vertex:v2 vp:name "Jill"
          vp:age 35 .
vertex:v3 vp:name "Frank";
          vp:age 23 .
vertex:v4 vp:name "Susan";
          vp:age 50 .
edge:e5 { vertex:v1 label:friend_of vertex:v2 .
          edge:e5   ep:weight 1.0 . }
edge:e6 { vertex:v1 label:friend_of vertex:v3 .
          edge:e6   ep:weight 2.0 . }
edge:e7 { vertex:v2 label:friend_of vertex:v3 .
          edge:e7   ep:weight 1.5 . }
edge:e8 { vertex:v2 label:friend_of vertex:v4 .
          edge:e8   ep:weight 1.0 . }

図11-1 等価なプロパティ・グラフと、同じグラフのRDF表現

図11-1の説明が続きます
「図11-1 等価なプロパティ・グラフと、同じグラフのRDF表現」の説明

この図で、上に示されているプロパティ・グラフ・モデルは、下に示されているRDFモデルよりも単純です。どちらのモデルにも、4名の人物 (John、Jill、Frank、Susan)を表す交点(ノード)がありますが、プロパティ・グラフ・モデルには、名前とラベルの情報を示す簡単なボックスがあります。プロパティ・グラフ・モデルでは、次の接頭辞で表現されたプロパティを持つエッジが、多数表示されています。

  • PREFIX edge: <http://xminx,oracle.com/pg/edge/>

  • PREFIX vertex: <http://xminx,oracle.com/pg/vertex/>

  • PREFIX ep: <http://xminx,oracle.com/pg/property/edge/>

  • PREFIX vp http://xminx,oracle.com/pg/property/vertex/>

  • PREFIX label: <http://xminx,oracle.com/pg/property/edge/label/>

11.2 プロパティ・グラフ・リレーショナル・スキーマに対するR2RMLマッピング

あらかじめ組み込まれているR2RMLを使用して、プロパティ・グラフ・リレーショナル・スキーマからRDFビューを構築することができます。

R2RMLマッピングの単純化と、NVARCHARからVARCHARへの値の変換を目的として、ヘルパー・ビューがいくつか作成されます。次の出力に、そうしたビューが示されています(RDFビュー・モデル名をM1、プロパティ・グラフ名をG1、ユーザー名をUSERとしています)。なお、エッジ・ラベルとプロパティ名を示すサブストリングの長さはカスタマイズ可能で、さらにこの表に値が格納されるよう指定した場合(options=>'GT_TABLE=T')、M1$GTビューがG1GT$表から直接選択されます。

-- 5 VT$ views --
-- Varchar --
create or replace view "USER"."M1$V1" as
select
  "VID",
  to_char(substr("K",1,200)) KC,
  "T",
  to_char("V") VC,
  "SL",
  "VTS",
  "VTE",
  "FE"
from  "USER"."G1VT$"
where T=1;

-- Number --
create or replace view "USER"."M1$V2" as
select
  "VID",
  to_char(substr("K",1,200)) KC,
  "T",
  "VN",
  "SL",
  "VTS",
  "VTE",
  "FE"
from  "USER"."G1VT$"
where T IN (2,3,4);

-- DateTime --
create or replace view "USER"."M1$V3" as
select
  "VID",
  to_char(substr("K",1,200)) KC,
  "T",
  "VT",
  "SL",
  "VTS",
  "VTE",
  "FE"
from  "USER"."G1VT$"
where T=5;

-- Boolean --
create or replace view "USER"."M1$V4" as
select
  "VID",
  to_char(substr("K",1,200)) KC,
  "T",
  DECODE("V",'y',to_char('true'),
             'Y',to_char('true'),
             'n',to_char('false'),
             'N',to_char('false')) VB,
  "SL",
  "VTS",
  "VTE",
  "FE"
from  "USER"."G1VT$"
where T=6; 

-- ID View –
create or replace view "USER"."M1$VT" as
select DISTINCT
  "VID"
from "USER"."G1VT$";

-- 4 GE$ Views --
-- Varchar --
create or replace view "USER"."M1$G1" as
select
  "EID",
  "SVID",
  "DVID",
  "EL",
  to_char(substr("K",1,200)) KC,
  "T",
  to_char("V") VC,
  "SL",
  "VTS",
  "VTE",
  "FE"
from "USER"."G1GE$"
where T=1;

-- Number --
create or replace view "USER"."M1$G2" as
select
  "EID",
  "SVID",
  "DVID",
  "EL",
  to_char(substr("K",1,200)) KC,
  "T",
  "VN",
  "SL",
  "VTS",
  "VTE",
  "FE"
from "USER"."G1GE$"
where T IN (2,3,4);

-- DateTime --
create or replace view "USER"."M1$G3" as
select
  "EID",
  "SVID",
  "DVID",
  "EL",
  to_char(substr("K",1,200)) KC,
  "T",
  "VT",
  "SL",
  "VTS",
  "VTE",
  "FE"
from "USER"."G1GE$"
where T=5;

-- Boolean --
create or replace view "USER"."M1$G4" as
select
  "EID",
  "SVID",
  "DVID",
  "EL",
  to_char(substr("K",1,200)) KC,
  "T",
  DECODE("V",'y',to_char('true'),
             'Y',to_char('true'),
             'n',to_char('false'),
             'N',to_char('false')) VB,
  "SL",
  "VTS",
  "VTE",
  "FE"
from "USER"."G1GE$"
where T=6;

-- GT$ View –
create or replace view "USER"."M1$GT" as
select DISTINCT
  "EID",
  "SVID",
  "DVID",
  to_char(substr("EL",1,200)) LC
from "USER"."G1GE$";

こうしたビューを使用する組込みのR2RMLマッピングは、次の出力にTurtle形式で示されています。

@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix rr:    <http://www.w3.org/ns/r2rml#>.
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#>.
@prefix pg:    <http://xmlns.oracle.com/pg/>.
@prefix pgvtpr: <http://xmlns.oracle.com/pg/property/vertex/>.
@prefix pgedpr: <http://xmlns.oracle.com/pg/property/edge/>.
# Vertex Property views ===============================================
pg:TMap_VERTEXPR_VC_TAB
  rr:logicalTable [ rr:tableName "\"USER\".\"M1$V1\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/vertex/v{VID}" ; 
    rr:class pg:VERTEX ] ;
  rr:predicateObjectMap [ 
    rr:predicateMap [ 
      rr:template "http://xmlns.oracle.com/pg/property/vertex/{KC}" ] ; 
    rr:objectMap [ rr:column "VC" ]
]
.
pg:TMap_VERTEXPR_VN_TAB
  rr:logicalTable [ rr:tableName "\"USER\".\"M1$V2\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/vertex/v{VID}" ; 
    rr:class pg:VERTEX ] ;
  rr:predicateObjectMap [ 
    rr:predicateMap [ 
      rr:template "http://xmlns.oracle.com/pg/property/vertex/{KC}" ] ; 
    rr:objectMap [  
      rr:column "VN" ; 
      rr:datatype xsd:decimal ]
]
.
pg:TMap_VERTEXPR_VT_TAB
  rr:logicalTable [ 
    rr:tableName "\"USER\".\"M1$V3\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/vertex/v{VID}" ; 
    rr:class pg:VERTEX ] ;
  rr:predicateObjectMap [ 
    rr:predicateMap [ 
      rr:template "http://xmlns.oracle.com/pg/property/vertex/{KC}" ] ; 
    rr:objectMap [ 
      rr:column "VT" ; 
      rr:datatype xsd:dateTime ] 
]
.
pg:TMap_VERTEXPR_VB_TAB
  rr:logicalTable [ 
    rr:tableName "\"USER\".\"M1$V4\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/vertex/v{VID}" ; 
    rr:class pg:VERTEX ] ;
  rr:predicateObjectMap [ 
    rr:predicateMap [ 
      rr:template "http://xmlns.oracle.com/pg/property/vertex/{KC}" ] ; 
    rr:objectMap [ 
      rr:column "VB" ; 
      rr:datatype xsd:boolean ] 
]
.
# VERTEX ID view ==============================================
pg:TMap_VERTEXID_TAB
  rr:logicalTable [ 
    rr:tableName "\"USER\".\"M1$VT\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/vertex/v{VID}" ; 
    rr:class pg:VERTEX ] ;
  rr:predicateObjectMap [
    rr:predicate pgvtpr:id ;
    rr:objectMap [ 
      rr:column "VID" ] 
  ]
.
# Edge Property views ===============================================
pg:TMap_EDGEPR_VC_TAB
  rr:logicalTable [ 
    rr:tableName "\"USER\".\"M1$G1\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ; 
    rr:graphMap [ 
      rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ] ] ;
  rr:predicateObjectMap [ 
    rr:predicateMap [ 
      rr:template "http://xmlns.oracle.com/pg/property/edge/{KC}" ] ; 
    rr:objectMap [ 
      rr:column "VC" ]
  ]
.
pg:TMap_EDGEPR_VN_TAB
  rr:logicalTable [ 
    rr:tableName "\"USER\".\"M1$G2\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ; 
    rr:graphMap [ 
      rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ] ] ;
  rr:predicateObjectMap [ 
    rr:predicateMap [ 
      rr:template "http://xmlns.oracle.com/pg/property/edge/{KC}" ] ; 
    rr:objectMap [ 
      rr:column "VN" ; 
      rr:datatype xsd:decimal ]
  ]
.
pg:TMap_EDGEPR_VT_TAB
  rr:logicalTable [ 
    rr:tableName "\"USER\".\"M1$G3\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ; 
    rr:graphMap [ 
      rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ] ] ;
  rr:predicateObjectMap [ 
    rr:predicateMap [ 
      rr:template "http://xmlns.oracle.com/pg/property/edge/{KC}" ] ; 
    rr:objectMap [ 
      rr:column "VT" ; 
      rr:datatype xsd:dateTime ] 
  ]
.
pg:TMap_EDGEPR_VB_TAB
  rr:logicalTable [ 
    rr:tableName "\"USER\".\"M1$G4\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ; 
    rr:graphMap [ 
      rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ] ] ;
  rr:predicateObjectMap [ 
    rr:predicateMap [ 
      rr:template "http://xmlns.oracle.com/pg/property/edge/{KC}" ] ; 
    rr:objectMap [ 
      rr:column "VB" ; 
      rr:datatype xsd:boolean ] 
  ]
.
# Edge IDLABEL views ==========================================
pg:TMap_EDGEIDLABEL_TAB
  rr:logicalTable [ 
    rr:tableName "\"USER\".\"M1$GT\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ; 
    rr:class pg:EDGE ; 
    rr:graphMap [ 
      rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ] ] ;
  rr:predicateObjectMap [
    rr:predicate pgedpr:id ;
    rr:objectMap [ 
      rr:column "EID" ] 
  ] ;
  rr:predicateObjectMap [
    rr:predicate pgedpr:label ;
    rr:objectMap [ 
      rr:column "LC" ] 
  ]
.
# Edge views ===================================================
pg:TMap_EDGE_TAB
  rr:logicalTable [ 
    rr:tableName "\"USER\".\"M1$GT\"" ] ;
  rr:subjectMap [ 
    rr:template "http://xmlns.oracle.com/pg/vertex/v{SVID}" ;
    rr:graphMap [ 
      rr:template "http://xmlns.oracle.com/pg/edge/e{EID}" ] ] ;
  rr:predicateObjectMap [ 
    rr:predicateMap [ 
      rr:template "http://xmlns.oracle.com/pg/label/{LC}" ] ;
    rr:objectMap [ 
      rr:template "http://xmlns.oracle.com/pg/vertex/v{DVID}" ; 
      rr:termType rr:IRI ] 
  ]
.

11.3 プロパティ・グラフRDFビューの作成と保守のためのPL/SQL API

SEM_APISパッケージのサブプログラムにより、プロパティ・グラフRDFの作成と保守が簡潔になっています。

そうしたサブプログラムのリ参照情報と使用法は、「SEM_APIS Package Subprograms」の章を参照してください。

既存のモデルからプロパティ・グラフ・ビューを作成するには、SEM_APIS.CREATE_PG_RDFVIEWプロシージャを使用します。

プロパティ・グラフRDFビューを削除するには、SEM_APIS.DROP_PG_RDFVIEWを使用します。

RDFビューに対する問合せで高いパフォーマンスを得るには、プロパティ・グラフ表に索引を作成する必要があります。そうした表には索引スキームをいくつでも作成できますが、便宜上、SEM_APIS.BUILD_PG_RDFVIEW_INDEXESプロシージャが用意されています。(このプロシージャで作成された索引すべてを削除するには、SEM_APIS.DROP_PG_RDFVIEW_INDEXESプロシージャを使用します)。

RDF語句で正規と認められるものに対してVALUE_ID値を(または、用語が存在しない場合にNULL値を)返すには、SEM_APIS.RES2VID関数を使用できます。

11.4 プロパティ・グラフ・データを使用したサンプルRDFワークフロー

ここでは、プロパティ・グラフ・データを使用したサンプルRDFワークフローを示します。

最初に示す例では、M1という名前のRDFビューを、Oracle Databaseに格納されたG1という名前のプロパティ・グラフから作成し、そのビューに対し索引を作成します。もう一つの例では、SEM_MATCH表関数を使用したSPARQL問合せを実行します。

例11-1 RDFビューと索引の作成

-- Create a property graph RDF view
EXECUTE sem_apis.create_pg_rdfview('M1','G1');
-- Create indexes
EXECUTE sem_apis.build_pg_rdfview_indexes('G1');

例11-2 Johnの友人すべての名前と年齢の検索

SELECT name$rdfterm, age$rdfterm
FROM TABLE(SEM_MATCH(
 'PREFIX edge: <http://xmlns.oracle.com/pg/edge/>
  PREFIX vertex: <http://xmlns.oracle.com/pg/vertex/>
  PREFIX ep: <http://xmlns.oracle.com/pg/property/edge/>
  PREFIX vp: <http://xmlns.oracle.com/pg/property/vertex/>
  PREFIX label: <http://xmlns.oracle.com/pg/property/edge/label/>
  SELECT ?name ?age
  WHERE { 
    ?v1 vp:name "John" .
    ?v1 label:friend_of ?v2 .
    ?v2 vp:name ?name .
    ?v2 vp:age ?age . }'
, sem_models('M1')
, null, null, null, null
, ' PLUS_RDFT=VC '));

例11-3 Johnの親友すべての名前と年齢の検索(重み> 1.5)

SELECT name$rdfterm, age$rdfterm
FROM TABLE(SEM_MATCH(
 'PREFIX edge: <http://xmlns.oracle.com/pg/edge/>
  PREFIX vertex: <http://xmlns.oracle.com/pg/vertex/>
  PREFIX ep: <http://xmlns.oracle.com/pg/property/edge/>
  PREFIX vp: <http://xmlns.oracle.com/pg/property/vertex/>
  PREFIX label: <http://xmlns.oracle.com/pg/property/edge/label/>
  SELECT ?name ?age
  WHERE { 
    ?v1 vp:name "John" .
    GRAPH ?e { 
      ?v1 label:friend_of ?v2 .
      ?e ep:weight ?w .
      FILTER (?w > 1.5) 
    }
    ?v2 vp:name ?name .
    ?v2 vp:age ?age . }'
, sem_models('M1')
, null, null, null, null
, ' PLUS_RDFT=VC '));

例11-4 Johnの最も親しい友人の検索(エッジの重みが最大)

SELECT name$rdfterm
FROM TABLE(SEM_MATCH(
 'PREFIX edge: <http://xmlns.oracle.com/pg/edge/>
  PREFIX vertex: <http://xmlns.oracle.com/pg/vertex/>
  PREFIX ep: <http://xmlns.oracle.com/pg/property/edge/>
  PREFIX vp: <http://xmlns.oracle.com/pg/property/vertex/>
  PREFIX label: <http://xmlns.oracle.com/pg/property/edge/label/>
  SELECT ?name
  WHERE { 
    ?v1 vp:name "John" .
    GRAPH ?e { 
      ?v1 label:friend_of ?v2 .
      ?e ep:weight ?w . 
    }
    ?v2 vp:name ?name . }
  ORDER BY DESC(?w)
  LIMIT 1'
, sem_models('M1')
, null, null, null, null
, ' PLUS_RDFT=VC '));

11.5 プロパティ・グラフRDFビューの使用で特に留意すべき点

プロパティ・グラフRDFビューを使用する場合には、次の点に特別留意します。

  • 交点およびエッジについて、長さ4000バイトを超える値はサポートされていません。

  • エッジ・ラベルURIが生成される際、エッジ・ラベルの値はIRI上安全な形式(W3C R2RMLの規格に準拠した形式)に置き換えられます。

  • 交点とエッジ・プロパティの名前を表すURIが生成される際、交点とエッジ・プロティの名前はIRI上安全な形式(W3C R2RMLの規格に準拠した形式)に置き換えられます。

  • 交点およびエッジ・プロパティの値で文字列値のものに含まれる特殊文字および非ASCII文字は、エスケープされます(W3C N-Triple規格に準拠)。