7.8 RDF Graph support for Apache JenaによりSPARQL問合せでサポートされる関数

Support for Apache Jenaを介したSPARQL問合せでは、次に示す種類の関数を使用できます。

  • Jena ARQ問合せエンジンの関数ライブラリにある関数

  • 投影変数に関するOracle Databaseのネイティブ関数

  • ユーザー定義関数

7.8.1 ARQ関数ライブラリの関数

support for Apache Jenaを介したSPARQL問合せは、Jena ARQ問合せエンジンの関数ライブラリにある関数を使用できます。これらの問合せは、中間層で実行されます。

次の例は、upper-case関数とnamespace関数を使用します。これらの例で、接頭辞fn<http://www.w3.org/2005/xpath-functions#>、接頭辞afn<http://jena.hpl.hp.com/ARQ/function#>です。

PREFIX  fn: <http://www.w3.org/2005/xpath-functions#>
PREFIX  afn: <http://jena.hpl.hp.com/ARQ/function#>
SELECT (fn:upper-case(?object) as ?object1)
WHERE { ?subject dc:title ?object }

PREFIX  fn: <http://www.w3.org/2005/xpath-functions#>
PREFIX  afn: <http://jena.hpl.hp.com/ARQ/function#>
SELECT ?subject (afn:namespace(?object) as ?object1)
WHERE { ?subject <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?object } 

7.8.2 射影された変数に対するネイティブなOracle Database関数

support for Apache Jenaを介したSPARQL問合せは、射影変数に関するOracle Databaseのネイティブ・ファンクションを使用できます。これらの問合せとファンクションは、データベース内部で実行されます。この項で説明したファンクションは、ARQファンクション(「ARQファンクション・ライブラリのファンクション」を参照)とともには使用しないでください。

この項では、サポートされるネイティブ関数の一覧と、いくつかの例を示します。例で、接頭辞oextは、< http://oracle.com/semtech/jena-adaptor/ext/function#>です。

ノート:

前述のURLで、jena-adaptorの綴りに注意してください(これは、既存のアプリケーションとの互換性のために保持されており、問合せではこれを使用する必要があります)。Oracleドキュメントのスタイル・ガイドに従い、通常のテキストではadapterいう綴りを使用します。

  • oext:upper-literalは、リテラル値(長いリテラルを除く)を大文字に変換します。たとえば、次のようにします。

    PREFIX  oext: <http://oracle.com/semtech/jena-adaptor/ext/function#>
    SELECT (oext:upper-literal(?object) as ?object1)
    WHERE { ?subject dc:title ?object }
    
  • oext:lower-literalは、リテラル値(長いリテラルを除く)を小文字に変換します。たとえば、次のようにします。

    PREFIX  oext: <http://oracle.com/semtech/jena-adaptor/ext/function#>
    SELECT (oext:lower-literal(?object) as ?object1)
    WHERE { ?subject dc:title ?object }
    
  • oext:build-uri-for-idは、URI、bNodeまたはリテラルの値IDをURIフォームに変換します。たとえば、次のようにします。

    PREFIX  oext: <http://oracle.com/semtech/jena-adaptor/ext/function#>
    SELECT (oext:build-uri-for-id(?object) as ?object1)
    WHERE { ?subject dc:title ?object }
    

    出力の例は、次のようになります。<rdfvid:1716368199350136353>

    この関数の1つの用途は、Javaアプリケーションがメモリー内で、それらの値IDからURI、bNodeまたはリテラルの字句形式へのマッピングを保持できるようにすることです。RDF_VALUE$表は、Oracle Databaseでこのようなマッピングを提供します。

    変数?varについて、oext:build-uri-for-id(?var)のみが投影される場合、問合せへの応答に必要な内部表の結合操作がより少なくなるため、問合せのパフォーマンスはより高速になります。

  • oext:literal-strlenは、リテラル値(長いリテラルを除く)の長さを返します。たとえば、次のようにします。

    PREFIX  oext: <http://oracle.com/semtech/jena-adaptor/ext/function#>
    SELECT (oext:literal-strlen(?object) as ?objlen)
    WHERE { ?subject dc:title ?object }

7.8.3 ユーザー定義関数

support for Apache Jenaを介したSPARQL問合せは、データベースに格納されているユーザー定義関数を使用できます。

次の例で、長いリテラル(CLOB)および短いリテラルを処理する文字列長関数(my_strlen)を定義するとします。SPARQL問合せ側では、この関数をouext(http://oracle.com/semtech/jena-adaptor/ext/user-def-function#)という名前空間の下で参照できます。

PREFIX  ouext: <http://oracle.com/semtech/jena-adaptor/ext/user-def-function#>
SELECT ?subject ?object (ouext:my_strlen(?object) as ?obj1)
WHERE { ?subject dc:title ?object }

データベース内では、この機能を実装するために、my_strlenmy_strlen_clmy_strlen_lamy_strlen_ltおよびmy_strlen_vtの関数を定義します。概念的に、これらのファンクションの戻り値は、表7-1に示すようにマップされます。

表7-1 my_strlenの関数と戻り値の例

関数名 戻り値

my_strlen

<VAR>

my_strlen_cl

<VAR>$RDFCLOB

my_strlen_la

<VAR>$RDFLANG

my_strlen_lt

<VAR>$RDFLTYP

my_strlen_vt

<VAR>$RDFVTYP

SPARQLから参照できる1つのユーザー定義関数は、(RDF_VALUE$内の)RDFリソースの内部表現で位置合せするため、これを実装するために一連の関数(合計5つ)が使用されます。RDFリソースの値、言語、リテラル・タイプ、LONG値および値タイプに関して記述する5つの主要な列があり、これらの5つの列はSEM_MATCHを使用して選択されます。この場合、ユーザー定義関数は、5つの列で表される1つのRDFリソースをもう1つのRDFリソースに単純に変換します。

これらの関数は、次のように定義されます。

create or replace function my_strlen(rdfvtyp in varchar2,
                              rdfltyp in varchar2,
                              rdflang in varchar2,
                              rdfclob in clob,
                              value   in varchar2
                              ) return varchar2
 as
   ret_val  varchar2(4000);
 begin
   -- value
   if (rdfvtyp = 'LIT') then
     if (rdfclob is null) then
       return length(value);
     else
       return dbms_lob.getlength(rdfclob);
     end if;
   else
     -- Assign -1 for non-literal values so that application can
     -- easily differentiate
     return '-1';
   end if;
 end;
 /
 
 create or replace function my_strlen_cl(rdfvtyp in varchar2,
                              rdfltyp in varchar2,
                              rdflang in varchar2,
                              rdfclob in clob,
                              value   in varchar2
                              ) return clob
 as
 begin
   return null;
 end;
 /
 
 create or replace function my_strlen_la(rdfvtyp in varchar2,
                              rdfltyp in varchar2,
                              rdflang in varchar2,
                              rdfclob in clob,
                              value   in varchar2
                              ) return varchar2
 as
 begin
   return null;
 end;
 /
 
 create or replace function my_strlen_lt(rdfvtyp in varchar2,
                              rdfltyp in varchar2,
                              rdflang in varchar2,
                              rdfclob in clob,
                              value   in varchar2
                              ) return varchar2
 as
   ret_val  varchar2(4000);
 begin
   -- literal type
   return 'http://www.w3.org/2001/XMLSchema#integer';
 end;
 /
 
 create or replace function my_strlen_vt(rdfvtyp in varchar2,
                              rdfltyp in varchar2,
                              rdflang in varchar2,
                              rdfclob in clob,
                              value   in varchar2
                              ) return varchar2
 as
   ret_val  varchar2(3);
 begin
   return 'LIT';
 end;
 /

ユーザー定義関数には、VARCHAR2タイプのパラメータを指定することもできます。次の5つの関数は、ともに、部分文字列に整数(VARCHAR2形式)を受け入れ、部分文字列を戻すmy_shorten_str関数を定義します。(この例の部分文字列は12文字で、4000バイト以下である必要があります。)

-- SPARQL query that returns the first 12 characters of literal values.
-- 
PREFIX  ouext: <http://oracle.com/semtech/jena-adaptor/ext/user-def-function#>
SELECT (ouext:my_shorten_str(?object, "12") as ?obj1) ?subject
WHERE { ?subject dc:title ?object }
 
create or replace function my_shorten_str(rdfvtyp in varchar2,
                            rdfltyp in varchar2,
                            rdflang in varchar2,
                            rdfclob in clob,
                            value   in varchar2,
                            arg     in varchar2
                            ) return varchar2
as
 ret_val  varchar2(4000);
begin
 -- value
 if (rdfvtyp = 'LIT') then
   if (rdfclob is null) then
     return substr(value, 1, to_number(arg));
   else
     return dbms_lob.substr(rdfclob, to_number(arg), 1);
   end if;
 else
   return null;
 end if;
end;
/
 
create or replace function my_shorten_str_cl(rdfvtyp in varchar2,
                            rdfltyp in varchar2,
                            rdflang in varchar2,
                            rdfclob in clob,
                            value   in varchar2,
                            arg     in varchar2
                            ) return clob
as
 ret_val  clob;
begin
 -- lob
 return null;
end;
/
 
create or replace function my_shorten_str_la(rdfvtyp in varchar2,
                            rdfltyp in varchar2,
                            rdflang in varchar2,
                            rdfclob in clob,
                            value   in varchar2,
                            arg     in varchar2
                            ) return varchar2
as
 ret_val  varchar2(4000);
begin
 -- lang
 if (rdfvtyp = 'LIT') then
   return rdflang;
 else
   return null;
 end if;
end;
/
 
create or replace function my_shorten_str_lt(rdfvtyp in varchar2,
                            rdfltyp in varchar2,
                            rdflang in varchar2,
                            rdfclob in clob,
                            value   in varchar2,
                            arg     in varchar2
                            ) return varchar2
as
 ret_val  varchar2(4000);
begin
 -- literal type
 ret_val := rdfltyp;
 return ret_val;
end;
/
 
create or replace function my_shorten_str_vt(rdfvtyp in varchar2,
                            rdfltyp in varchar2,
                            rdflang in varchar2,
                            rdfclob in clob,
                            value   in varchar2,
                            arg     in varchar2
                            ) return varchar2
as
 ret_val  varchar2(3);
begin
 return 'LIT';
end;
/