プライマリ・コンテンツに移動
Oracle® Database JavaのためのSODA開発者ガイド
リリース1.0
E85936-01
目次へ移動
目次
索引へ移動
索引

前
次

1 JavaのためのSODA

Java APIのためのOracle SODAについて説明し、そのインストールと使用方法についても説明します。ここでの内容は、Java、JSONおよびOracle Databaseを理解していることが前提となっています。ここでのコード・サンプルはJavaコードです。

Oracle DatabaseにおけるJSONの詳細は、『Oracle Database JSON開発者ガイド』を参照してください。

注意:

JavaのためのSODAでは、RFC 4627に記載されているJSONのバージョンがサポートされています。詳細は、「JavaのためのSODAによるドキュメントの作成および使用」を参照してください。

JavaのためのSODAの前提条件

JavaのためのSODAを使用する前に、Java環境を構成する必要があります。

Oracle DatabaseでJavaのためのSODAを使用するには:

  • Java Runtime Environment 1.6 (JRE 1.6)が必要です。

  • 次のJavaアーカイブ(JAR)ファイルをCLASSPATH環境変数に指定するか、コマンドライン・オプションclasspathを使用して渡す必要があります。

    • orajsoda.jar (JavaのためのSODAのRDBMS実装)。https://github.com/oracle/soda-for-java/releasesで最新バージョンを取得してください。

    • ojdbc6.jar (Oracle Database 12cリリース1 (12.1.0.2)に付属しているOracle JDBC JARファイル)

    • javax.json-1.0.4.jar (JSR353: JSON処理用のJava API)

  • Oracle Database 12cリリース1 (12.1.0.2)およびマージ・ラベル・リクエスト(MLR)バンドル・パッチ20885778が必要です。

    パッチは、My Oracle Support(https://support.oracle.com)から入手してください。「パッチと更新版」タブを選択します。パッチ番号の20885778を検索するか、または直接次のURL: https://support.oracle.com/rs?type=patch&id=20885778にアクセスします。

注意:

データベース文字セットにはAL32UTF8 (Unicode)を使用することをお薦めします。そうでない場合は、次のようになります。

  • データベース文字セットへの変換は精度が失われるため、入力中にJavaのためのSODAでデータが変更される可能性があります。

  • 例による問合せ(QBE)で、予測不能な結果が返される可能性があります。

JavaのためのSODAの概要

Simple Oracle Document Access (SODA)はNoSQL形式のAPIセットであり、これを使用すると、Oracle Databaseのドキュメントのコレクションを作成および格納でき、Structured Query Language (SQL)や、ドキュメントのデータがどのようにデータベースに格納されているかを理解していなくても、そのコレクションの取得や問合せを行うことができます。

JavaのためのSODAはSODAを提供するJava APIです。これを使用して、あらゆる種類のドキュメントについて作成、読取り(取得)、更新および削除(CRUD)操作を実行でき、これを使用してJSONドキュメントを問い合せることができます。

Oracleリレーショナル・データベース管理システム(RDBMS)では、JSONデータの格納および問合せがサポートされています。この機能にアクセスするには、Structured Query Language (SQL)、特殊なJSON SQL演算子およびJava Database Connectivity (JDBC)が必要です。

JavaのためのSODAでは、次のSODA抽象化によってSQL/JDBCプログラミングの複雑化が抑えられます。

  • データベース

  • コレクション

  • ドキュメント

データベースにはコレクションが含まれており、各コレクションにはドキュメントが含まれています。JavaのためのSODAは主にJSONドキュメントを使用するために設計されていますが、ドキュメントはMultipurpose Internet Mail Extensions (MIME)タイプにすることができます。

JavaのためのSODAでは、コレクションに対してCRUD操作を提供しています。これらの操作はJSON SQL演算子を使用してSQLに透過的に変換され、JDBCによって実行されます。

(SODAの)データベースはOracle Databaseスキーマに類似しており、コレクションは表に類似しており、ドキュメントはドキュメント・キーに1つの列とドキュメント・コンテンツに別の列を持つ表の行に類似しています。

このドキュメントのその他のトピックでは、JavaのためのSODAの様々な機能について説明します。特定のJavaメソッドの詳細は、JavaのためのSODAのJavadocを参照してください。

JavaのためのSODAの使用

JavaのためのSODAにアクセスする方法、およびこれを使用してコレクションに対する作成、読取り(取得)および削除(CRUD)操作を実行する方法について説明します。

(CRUD操作は、このドキュメントでは読取りおよび書込み操作とも呼ばれています。)

JavaのためのSODAのスタート・ガイド

JavaのためのSODAにアクセスする方法、およびこれを使用してデータベース・コレクションを作成し、ドキュメントをコレクションに挿入し、コレクションからドキュメントを取得する方法について説明します。

次の手順に従って、JavaのためのSODAを開始します。

  1. JavaのためのSODAを使用するための前提条件がすべて満たされていることを確認します。「JavaのためのSODAの前提条件」を参照してください。

  2. コレクションの格納に使用するデータベース・スキーマ(ユーザー・アカウント)を特定し、データベース・ロールSODA_APPをそのスキーマに付与します。

    GRANT SODA_APP TO schemaName;
    
  3. 必要なすべてのjarファイルおよびファイルtestSoda.java (例1-1のテキストに記載)をディレクトリに配置します。

  4. testSoda.javaで次のようにします。

    • hostNameportおよびserviceNameを、Oracle RDBMSインスタンスのホスト名、ポートおよびサービス名に置き換えます。

    • schemaNameおよびpasswordを手順2で特定したデータベース・スキーマの名前とパスワードに置き換えます。これに例1-1で作成したコレクションが格納されます。

  5. cdコマンドを使用して、jarファイルとファイルtestSoda.javaが含まれているディレクトリに移動します。

  6. 次のコマンドを実行します。

    javac -classpath "*" testSoda.java
    java -classpath "*:." testSoda
    

    2番目のコマンドのかわりに、オプションで次のコマンドを使用できます。これを実行すると、コレクションがドロップされ、コレクションとそのメタデータの格納に使用されるデータベース表がクリーンアップされます。

    java -classpath "*:." testSoda drop
    

    ここで引数dropを使用すると、コレクションを適切にドロップするメソッドdrop()が呼び出されます。

    注意:

    SQLを使用して、コレクションの基礎となるデータベース表をドロップしないでください。表に格納されるドキュメントに加えて、コレクションにはOracle Databaseにも残っているメタデータが含まれています。コレクション表をドロップしても、関連付けられているメタデータはドロップされません

JavaのためのSODAを使用するには、最初にJDBC接続をオープンする必要があります。これについては例1-1に示しています。JDBC接続をオープンする方法の詳細は、『Oracle Database JDBC開発者ガイド』を参照してください。

例1-1 testSoda.java

この例では、プレースホルダhostNameportschemaNameおよびpasswordをデータベース・インスタンスの適切な情報に置き換えます。

import java.sql.Connection;
import java.sql.DriverManager;
 
import oracle.soda.rdbms.OracleRDBMSClient;

import oracle.soda.OracleDatabase;
import oracle.soda.OracleCursor;
import oracle.soda.OracleCollection;
import oracle.soda.OracleDocument;
import oracle.soda.OracleException;
 
import java.util.Properties;

import oracle.jdbc.OracleConnection;
 
public class testSoda
{
  public static void main(String[] arg)
  {
      // Set up the JDBC connection string, schemaName, and password.
      // Replace with info appropriate for your Oracle Database instance.
      String url = "jdbc:oracle:thin:@//hostName:port/serviceName";
      Properties props = new Properties();
      props.setProperty("user", schemaName);
      props.setProperty("password", password);
 
      OracleConnection conn = null;
 
      try
      {
        // Get a JDBC connection to an Oracle instance.
        conn = (OracleConnection) DriverManager.getConnection(url, props);

        // Enable JDBC implicit statement caching
        conn.setImplicitCachingEnabled(true);
        conn.setStatementCacheSize(50);
 
        // Get an OracleRDBMSClient - starting point of SODA for Java application.
        OracleRDBMSClient cl = new OracleRDBMSClient();
 
        // Get a database.
        OracleDatabase db = cl.getDatabase(conn);
 
        // Create a collection with the name "MyJSONCollection".
        // This creates a database table, also named "MyJSONCollection", to store the collection.
        OracleCollection col = db.admin().createCollection("MyJSONCollection");
 
        // Create a JSON document.
        OracleDocument doc =
          db.createDocumentFromString("{ \"name\" : \"Alexander\" }");
 
        // Insert the document into a collection.
        col.insert(doc);
 
        // Find all documents in the collection.
        OracleCursor c = null;
 
        try 
        {
          c = col.find().getCursor();
          OracleDocument resultDoc;
 
          while (c.hasNext())
          {
            // Get the next document.
            resultDoc = c.next();
 
            // Print document components
            System.out.println ("Key:         " + resultDoc.getKey());
            System.out.println ("Content:     " + resultDoc.getContentAsString());
            System.out.println ("Version:     " + resultDoc.getVersion());
            System.out.println ("Last modified: " + resultDoc.getLastModified());
            System.out.println ("Created on:    " + resultDoc.getCreatedOn());
            System.out.println ("Media:         " + resultDoc.getMediaType());
            System.out.println ("\n");
          }
        }
        finally
        {
          // IMPORTANT: YOU MUST CLOSE THE CURSOR TO RELEASE RESOURCES.
          if (c != null) c.close();
        }
 
        // Drop the collection, deleting the table underlying it and the collection metadata.
        if (arg.length > 0 && arg[0].equals("drop")) {
          col.admin().drop();
          System.out.println ("\nCollection dropped");
        }
    }
    // SODA for Java throws a checked OracleException
    catch (OracleException e) { e.printStackTrace(); }
    catch (Exception e) { e.printStackTrace(); }
    finally 
    {
      try { if (conn != null)  conn.close(); }
      catch (Exception e) { }
    }
  }
}

JavaのためのSODAによる新規ドキュメント・コレクションの作成

JavaのためのSODAを使用して新規ドキュメント・コレクションを作成する方法について説明します。

Javaアプリケーションでは、最初にOracleRDBMSClientオブジェクトを作成します。これがJavaのためのSODAを使用するJavaアプリケーションの開始点になります。

OracleRDBMSClient client = new OracleRDBMSClient();

注意:

OracleRDBMSClientオブジェクトのclientはスレッドセーフです。ただし、他のJavaのためのSODAインタフェースはスレッドセーフではありません。複数のスレッド間でこれらを共有しないでください。

次に、JDBC接続をメソッドOracleClient.getDatabase()に渡し、OracleDatabaseオブジェクトを取得します。

OracleDatabase db = client.getDatabase(jdbcConnection);

注意:

SODAに渡すJDBC接続に対して暗黙的な文キャッシングを有効にすることをお薦めします。これにより、読取りおよび書込み操作のパフォーマンスを改善できます。読取りおよび書込み操作の基礎となる実装では、JDBCのプリコンパイルされた文が生成されます。

暗黙的なキャッシングを有効にしないと、読取りまたは書込み操作が作成されるたびに、JDBCのプリコンパイルされた新規の文が作成されます。暗黙的なキャッシングを有効にすると、JDBCのプリコンパイルされた新規の文はキャッシュに存在しない場合にのみ作成されます。

『Oracle Database JDBC開発者ガイド』および『Oracle Universal Connection Pool for JDBC開発者ガイド』も参照してください

コレクションの作成メソッドは、インタフェースOracleDatabaseAdminで使用可能です。このインタフェースにアクセスするには、OracleDatabaseオブジェクトでメソッドadmin()を呼び出します。

OracleDatabaseAdmin dbAdmin = db.admin();

次のコマンドを使用して、コレクション(OracleCollectionオブジェクト)を作成できます。ここで、collectionNameはコレクションの名前です。

OracleCollection col =  dbAdmin.createCollection("collectionName");

メソッドcreateCollection(String collectionName)では、Oracle Databaseに次のものが作成されます。

  • 永続的なデフォルトのコレクション・メタデータ。

  • 入力JDBC接続が構成されているスキーマ内のコレクションを格納するための表。

    デフォルトでは、表名はコレクション名から派生します。デフォルトで提供されているものと異なる表名が必要な場合、カスタム・コレクション・メタデータを使用して明示的に表名を指定します(次を参照)。

    デフォルトの表名は次のようにコレクション名から派生します。

    1. コレクション名の各ASCII制御文字および二重引用符(")はアンダースコア(_)に置き換わります。

    2. 次の条件のすべてが適用される場合、名前のすべての文字は大文字に変換され、表名を示します。この場合、SQLコードで表名を引用符で囲む必要はありません。これ以外の場合、表名を引用符で囲む必要があります。

      • 名前内の文字がすべて小文字か、すべて大文字である。

      • 名前がASCII文字で始まる。

      • 名前内の各文字がASCIIの英数字、アンダースコア(_)、ドル記号($)または番号記号(#)である。

        注意:

        Oracle識別子名でドル記号($)または番号記号(#)を使用しないことをお薦めします。

    次に例を示します。

    • コレクション名"col"と"COL"は、両方とも"COL"という名前になります。SQLで使用すると、表名は大/小文字の区別なく解釈されるため、二重引用符(")で囲む必要はありません。

    • コレクション名"myCol"は"myCol"という表名になります。SQLで使用すると、表名は大/小文字が区別されて解釈されるため、二重引用符(")で囲む必要があります。

    注意:

    メソッドcreateCollectionで使用された表名が、JDBC接続が構成されているスキーマにある既存の表の名前になる場合、メソッドではその表をコレクションにマップしようとします。この動作には表名がコレクション名から派生するデフォルト・ケースがあります。

デフォルトのコレクション・メタデータには次の特性があります。

  • コレクション内の各ドキュメントには次のドキュメント・コンポーネントがあります。

    • キー

    • コンテンツ

    • 作成時のタイムスタンプ

    • 最終変更のタイムスタンプ

    • バージョン

  • コレクションはJSONドキュメントのみを格納できます。

  • ドキュメント・キーは、コレクションに追加したドキュメントに自動的に生成されます。

ほとんどの場合、デフォルトのコレクション構成をお薦めしますが、コレクションは高度な構成が可能です。コレクションを作成する場合、次のような項目を指定できます。

  • 記憶域の詳細。たとえば、コレクションを格納する表の名前、列の名前とデータ型など。

  • 作成時のタイムスタンプ、最終変更のタイムスタンプおよびバージョン用の列の有無。

  • コレクションがJSONドキュメントのみを格納できるかどうか。

  • ドキュメント・キーの生成方式、およびドキュメント・キーをクライアントで割り当てるかまたは自動的に生成するか。

  • バージョンの生成方式。

このように構成可能であるため、新規コレクションを既存の表にマップすることもできます。

デフォルト以外の方法でコレクションを構成するには、カスタム・コレクション・メタデータのJSON OracleDocumentインスタンスを作成して、これをメソッドcreateCollection(String collectionName, OracleDocument collectionMetadata)に渡す必要があります。このOracleDocumentインスタンスを容易に作成および生成するには、OracleRDBMSMetadataBuilderを使用できます。

コレクションの記憶域および構成の詳細が重要でない場合、例1-2のように、メソッドcreateCollection(collectionName)を使用します。

コレクションがオープンしている場合にのみ、これを検索および変更できます。新しく作成したコレクションがオープンしているのは、セッションの存続期間です。

注意:

特に記載のないかぎり、このドキュメントでは、コレクションはデフォルト構成を使用していると想定しています。

関連項目:

JavaのためのSODAによる既存のドキュメント・コレクションのオープン

OracleDatabaseのメソッドopenCollection()を使用して、既存のドキュメント・コレクションをオープンしたり、特定の名前が既存のコレクションを示すかどうかをテストできます。

例1-2では、myCollectionNameという名前のコレクションをオープンし、このコレクションを表すOracleCollectionオブジェクトを返します。返された値がnullの場合、myCollectionNameという名前のコレクションは存在しません。

例1-2 既存のドキュメント・コレクションのオープン

OracleCollection ocol = db.openCollection("myCollectionName");

JavaのためのSODAによる指定コレクションの存在の確認

OracleDatabaseのメソッドopenCollection()を使用して、指定したコレクションが存在するかどうかを確認できます。コレクションの引数が既存のコレクションを示さない場合、nullを返し、それ以外の場合、その名前のコレクションをオープンします。

例1-2では、myCollectionNameが既存のコレクションを示さない場合、ocolが値nullを割り当てられます。

JavaのためのSODAによる既存のコレクションの検出

OracleDatabaseAdminのメソッドgetCollectionNamesを使用して、既存のコレクションを検出できます。

例1-3では、最も単純な署名を持つメソッドgetCollectionNamesを使用してこれを示します。このメソッドには引数はありません。例では、既存のコレクションの名前を出力します。

例1-3 すべての既存のコレクションの名前の出力

List<String> names =  db.admin().getCollectionNames();

for (String name : names)
 System.out.println ("Collection name: " + name);

JavaのためのSODAによるドキュメント・コレクションのドロップ

OracleCollectionAdminのメソッドdrop()を使用して、ドキュメント・コレクションをドロップします。

例1-4では、コレクションcolをドロップします。

注意:

これは、コレクションをドロップする適切な方法(メソッドdrop()を使用)です。SQLを使用して、コレクションの基礎となるデータベース表をドロップしないでください。コレクションには、コレクション表に格納されたドキュメントに加えて、永続化されたメタデータがあります。

注意:

メソッドdrop()を使用する前に、コレクションへのすべての書込みをコミットしてください。drop()が正常に終了するには、コレクションに対してコミットされていないすべての書込みを最初にコミットする必要があります。そうでない場合は、例外が発生します。

例1-4 ドキュメント・コレクションのドロップ

col.admin().drop();

コレクションをドロップして再作成する必要がある場合...

SODAを使用する通常のアプリケーションを日常的に使用する場合、コレクションをドロップして再作成する必要はありません。ただし、なんらかの理由でこれを行う必要がある場合、次に示す重要なガイドラインを確認してください。

SODAオブジェクトを使用するアプリケーションが実行中の場合、コレクションをドロップしてから、異なるメタデータを使用してこれを再作成しないでください。すべてのライブSODAオブジェクトが解放されるように、コレクションを再作成する前にこのようなアプリケーションをすべて停止します。

コレクションのドロップだけでは、問題は発生しません。ドロップしたコレクションに対応する古いOracleCollectionオブジェクトへの読取りおよび書込み操作でエラーが発生します。コレクションをドロップして同じメタデータを持つコレクションを再作成しても、問題はありません。

ただし、異なるメタデータでコレクションを再作成して、SODAオブジェクトを使用するライブ・アプリケーションが存在する場合、古いコレクション・オブジェクト(OracleCollectionインスタンス)にアクセスするというリスクが生じます。この場合、エラーは発生しません。

コレクション・メタデータがキャッシュされている場合に、このリスクが高くなります。キャッシングが有効になっている場合、コレクションがドロップされても、(共有またはローカルの)キャッシュでは古いコレクション・オブジェクトのエントリを返します。

JavaのためのSODAによるドキュメントの作成および使用

JavaのためのSODAによるドキュメントの作成および使用方法について説明します。

JavaのためのSODAは、JavaインタフェースOracleDocumentを使用したドキュメントを提示します。このインタフェースは主にJSONドキュメントを提示するために設計されていますが、他のコンテンツ・タイプもサポートしています。OracleDocumentは、単にコンテンツを配置するためのものです。

OracleDocumentインスタンスにJSONコンテンツを作成するには、お気に入りのパッケージ(JSR353、JSON処理のためのJava API (https://jsonp.java.net/)など)を使用できます。次に、単純なJSONドキュメントの例を示します。

{ "name" :    "Alexander",
  "address" : "1234 Main Street",
  "city" :    "Anytown",
  "state" :   "CA",
  "zip" :     "12345"
}

注意:

JavaのためのSODAでは、JSONコンテンツはRFC 4627に準拠する必要があります。特に、JSONコンテンツはオブジェクト(前述の例を参照)または配列にする必要があり、スカラー値にすることはできません。たとえば、RFC 4627によると、文字列値"hello"は、それ自体有効なJSONコンテンツではありません。

JavaのためのSODAにおいても、JSONコンテンツのエンコーディングはUTF-8またはUTF-16 (ビッグ・エンディアン(BE)またはリトル・エンディアン(LE))である必要があります。RFC 4627ではUTF-32 (BEおよびLE)エンコーディングも許可していますが、JavaのためのSODAではこれをサポートしていません。

バイト配列またはStringインスタンスとして表されるコンテンツからOracleDocumentインスタンスを作成するには、(OracleDatabaseによりOracleDocumentFactoryから継承される)次のメソッドをそれぞれ使用します。

  • createDocumentFromByteArray()

  • createDocumentFromString()

注意:

JavaのためのSODAで使用されるドキュメントは約2GBに制限されます。

ドキュメントには次のコンポーネントがあります。

  • キー

  • コンテンツ

  • 作成時のタイムスタンプ

  • 最終変更のタイムスタンプ

  • バージョン

  • メディア・タイプ(JSONドキュメントの場合、"application/json")

インタフェースOracleDocumentではドキュメント・コンポーネントへのアクセス用に取得メソッドを提供しています。ドキュメントに指定したコンポーネントがない場合、対応する取得メソッドはnullを返します。

メソッドcreateDocumentFromString()またはcreateDocumentFromByteArray()を呼び出してドキュメントを作成した場合、次のようになります。

  • メソッドの引数として、ドキュメント・キーを指定する必要があります。

    コレクションでは、各ドキュメントにキーが必要です。ドキュメントを作成する場合で、ドキュメントをコレクションに挿入する必要があり、挿入されるドキュメントに対してコレクションで自動的にキーを生成しない場合にのみ、キーを指定する必要があります。デフォルトでは、コレクションは自動的にドキュメント・キーを生成するように構成されます。

  • ドキュメント・コンテンツをメソッドの引数として指定できます(contentパラメータが必要ですが、値にnullを指定できます)。

  • メソッドでは、作成時タイムスタンプ、最終変更のタイムスタンプおよびバージョンをnullに設定します。

メソッドcreateDocumentFromString()およびcreateDocumentFromByteArray()には、それぞれ複数のバリアントがあります。

  • 最も単純なバリアントはドキュメント・コンテンツのみを受け入れます。メディア・タイプは"application/json"にデフォルト設定されており、他のコンポーネントはnullにデフォルト設定されています。このバリアントは、ドキュメント・キーを自動的に生成するコレクションに挿入するドキュメントの作成に便利です。

  • 別のバリアントでは、ドキュメント・キーとドキュメント・コンテンツの両方を受け入れます。メディア・タイプは"application/json"にデフォルト設定されており、他のコンポーネントはnullにデフォルト設定されています。このバリアントは、クライアント割当てドキュメント・キーを持つコレクションに挿入するドキュメントの作成に便利です。

  • 最も柔軟性の高い(最も詳細な)バリアントでは、キー、コンテンツおよびコンテンツ・タイプを受け入れます。これを使用するとコンテンツ・タイプを指定できるため、このバリアントはJSON以外のドキュメントの作成に便利です。

例1-5では、コンテンツのみを含むOracleDocumentインスタンスを作成します。メディア・タイプは"application/json"にデフォルト設定されており、他のドキュメント・コンポーネントはnullにデフォルト設定されています。

例1-6では、ドキュメント・キーおよびコンテンツを含むOracleDocumentインスタンスを作成します。メディア・タイプは"application/json"にデフォルト設定されており、他のドキュメント・コンポーネントはnullにデフォルト設定されています。

JavaのためのSODAの書込み操作を使用してドキュメントをコレクションに書き込み、JavaのためのSODAの読取り操作を使用してコレクションからドキュメントを読み取ります。JavaのためのSODAの読取りおよび書込み操作については、次のトピックで説明します。

関連項目:

  • メソッドcreateDocumentFromString()およびcreateDocumentFromByteArray()に関する詳細は、OracleDocumentFactoryのJavadocを参照してください

  • 取得メソッドの詳細は、OracleDocumentのJavadocを参照してください

例1-5 JSONコンテンツを含むドキュメントの作成

OracleDocument doc =
  odb.createDocumentFromString("{ \"name\" : \"Alexander\"}");

// Get the content
String content = doc.getContentAsString();

// Get the content type (it is "application/json")
String contentType = doc.getContentType();

例1-6 ドキュメント・キーおよびJSONコンテンツを含むドキュメントの作成

OracleDocument doc
  = odb.createDocumentFromString("myKey", "{ \"name\" : \"Alexander\"}");

JavaのためのSODAによるトランザクションの処理

JavaのためのSODAが個々の読取りおよび書込み操作またはその操作のグループを単一のトランザクションとして処理するようにすることができます。

メソッドOracleClient.getDatabase()に渡すJDBC接続の自動コミット・モードにはオンまたはオフがあります。

自動コミット・モードがオンの場合、JavaのためのSODAの読取りおよび書込み操作は単一のトランザクションとして処理されます。操作が正常に終了すると、トランザクションは自動的にコミットします。操作が失敗すると、OracleExceptionまたはRuntimeExceptionがスローされ、トランザクションは自動的にロールバックします。JavaのためのSODAでは確認済の例外(OracleException、およびOracleExceptionから派生した例外)のみをスローします。ただし、JavaのためのSODAはJDBC上で構築されており、JavaのためのSODAが受け渡すRuntimeExceptionをスローできます。

自動コミットがオフの場合、JavaのためのSODAの複数の読取りまたは書込み操作を1つのトランザクションに結合できます。トランザクションが正常に終了すると、アプリケーションではメソッドcommit()をJDBC接続でコールしてこれを明示的にコミットする必要があります。トランザクションが失敗すると、OracleExceptionまたはRuntimeExceptionがスローされます。アプリケーションでは例外を処理し、メソッドrollback()をJDBC接続上で呼び出して明示的にトランザクションをロールバックする必要があります。(RuntimeExceptionは、前述したようにJDBCでのみスローできます。)

トランザクションのプログラミングを容易にするために、JavaのためのSODAではオプティミスティック・ロックをサポートしています。

JavaのためのSODAによるドキュメントのコレクションへの挿入

ドキュメントをコレクションに挿入するには、OracleCollectionのメソッドinsert(OracleDocument)またはinsertAndGet(OracleDocument)を呼び出します。コレクションがクライアント割当てキーで構成されておらず、入力ドキュメントがキーを指定していない場合、これらのメソッドでは、ドキュメント・キーが自動的に作成されます。

メソッドinsert(OracleDocument)はドキュメントのみをコレクションに挿入します。メソッドinsertAndGet(OracleDocument)では結果のドキュメントも返します。これにはドキュメント・キーおよび他の生成済ドキュメント・コンポーネント(コンテンツを除く)が含まれています。

両方のメソッドでは作成時のタイムスタンプ、最終変更のタイムスタンプおよびバージョンの値が自動的に設定されます(デフォルトの場合と同様にコレクションがこれらのコンポーネントを含めて自動的にバージョンを生成するように構成されている場合)。

注意:

コレクションがクライアント割当てドキュメント・キーで構成されていて(デフォルトの場合と異なるケース)、入力ドキュメントがコレクション内の既存のドキュメントを識別するキーを提供している場合、これらのメソッドは例外をスローします。例外を発生させるのではなく、入力ドキュメントで既存のドキュメントを置き換える場合、「JavaのためのSODAによるドキュメントのコレクションへの保存」を参照してください。

例1-7では、ドキュメントを作成し、メソッドinsert()を使用してこれをコレクションに挿入します。

例1-8では、ドキュメントを作成し、メソッドinsertAndGet()を使用してこれをコレクションに挿入してから、(コンポーネントが含まれている)結果のドキュメントから生成済コンポーネントをそれぞれ取得します。

多数のドキュメントを1つのコレクションに効率的に挿入するには、OracleCollectionのメソッドinsert(Iterator<OracleDocument>)またはinsertAndGet(Iterator<OracleDocument>)を呼び出します。これらのメソッドはinsert(OracleDocument)およびinsertAndGet(OracleDocument)に類似していますが、単一のドキュメントを処理するのではなく、複数のドキュメントを処理します。パラメータIterator<oracleDocument>は複数の入力ドキュメントに対するイテレータです。

メソッドinsertAndGet(Iterator<OracleDocument>)は結果ドキュメントのリスト(入力ドキュメントごとに1つのOracleDocumentインスタンス)を返します。このような結果ドキュメントには、それぞれドキュメント・キーおよび他の生成済ドキュメント・コンポーネント(コンテンツを除く)が含まれています。結果ドキュメントの順序は入力ドキュメントの順序と同じであり、結果ドキュメントと入力ドキュメントの相互関係を許可します。

関連項目:

メソッドinsert(OracleDocument)insertAndGet(OracleDocument)insert(Iterator<OracleDocument>)およびinsertAndGet(Iterator<OracleDocument>)の詳細は、OracleCollectionのJavadocを参照してください

例1-7 コレクションへのドキュメントの挿入

OracleDocument doc =
  db.createDocumentFromString("{ \"name\" : \"Alexander\"}");

col.insert(doc);

例1-8 コレクションへのドキュメントの挿入および結果ドキュメントの取得

OracleDocument doc =
  db.createDocumentFromString("{ \"name\" : \"Alexander\"}");

OracleDocument insertedDoc = col.insertAndGet(doc);

// Get the generated document key
String key = insertedDoc.getKey();
 
// Get the generated creation timestamp
String createdOn = insertedDoc.getCreatedOn();
 
// Get the generated last-modified timestamp
String lastModified = insertedDoc.getLastModified();
 
// Get the generated version
String version = insertedDoc.getVersion();

JavaのためのSODAによるドキュメントのコレクションへの保存

OracleCollectionのメソッドsave(OracleDocument)およびsaveAndGet(OracleDocument)を使用して、ドキュメントをコレクションに保存します。

これらのメソッドは、次の点を除いてメソッドinsert(OracleDocument)およびinsertAndGet(OracleDocument)と同様です: コレクションがクライアント割当てドキュメント・キーで構成されていて、入力ドキュメントがコレクション内のドキュメントを識別するキーを提供している場合、入力ドキュメントは既存のドキュメントを置き換えます。(この場合、メソッドinsert(OracleDocument)およびinsertAndGet(OracleDocument)は例外をスローします。)

注意:

デフォルトでは、コレクションは自動的に生成されたドキュメント・キーで構成されます。したがって、デフォルトのコレクションの場合、メソッドsave(OracleDocument)およびsaveAndGet(OracleDocument)は、それぞれメソッドinsert(OracleDocument)およびinsertAndGet(OracleDocument)と等価です。

例1-9では、メソッドsaveAndGet()を使用してクライアント割当てドキュメント・キーで構成されているコレクションにドキュメントを保存します。その後、キーと生成済ドキュメント・コンポーネント(コンテンツを除く)を結果ドキュメント(これらを含む)から取得します。

関連項目:

メソッドsave(OracleDocument)およびsaveAndGet(OracleDocument)の詳細は、OracleCollectionのJavadocを参照してください

例1-9 コレクションへのドキュメントの保存

OracleRDBMSClient cl = new OracleRDBMSClient();
OracleDatabase db = ...

// Configures the collection with client-assigned document keys
OracleDocument collMeta =
  cl.createMetadataBuilder().keyColumnAssignmentMethod("client").build();
OracleCollection cKeyColl = db.createCollection("collectionName", collMeta);

// For a collection configured with client-assigned document keys,
// you must provide the key for the input document.
OracleDocument cKeyDoc =
  db.createDocumentFromString("myKey", "{ \"name\" : \"Alexander\"}");

// If key "myKey" already identifies a document in the collection
// then cKeyDoc replaces the existing doc.
OracleDocument savedDoc = clientKeysColl.saveAndGet(cKeyDoc);

// Get document key ("myKey")
String key = savedDoc.getKey();

// Get the generated creation timestamp
String createdOn = savedDoc.getCreatedOn();
 
// Get the generated last-modified timestamp
String lastModified = savedDoc.getLastModified();
 
// Get the generated version
String version = savedDoc.getVersion();

JavaのためのSODAによるコレクションでのドキュメントの検索

コレクション内でドキュメントを検索するには、OracleCollectionのメソッドfind()を呼び出します。これは、コレクション内のすべてのドキュメントを検索する問合せを示すOracleOperationBuilderオブジェクトを返します。

問合せを実行するには、OracleOperationBuilderのメソッドgetCursor()を呼び出して、その結果のカーソルを取得します。次に、カーソルを使用して結果リスト内の各ドキュメントにアクセスします。結果リストに次のドキュメントがあるかどうかを判定し、次のドキュメントを取得するには、OracleCursorのメソッドhasNext()およびnext()をそれぞれ呼び出します。これについては例1-10およびこのガイドの他の例に示しています。

ただし、通常は直接OracleOperationBuilderオブジェクトを使用しても機能しません。かわりに、そのメソッドのいくつかをつなげて様々な検索操作を指定します。これについてはこのガイドの他の例で示します。ここでは、キーまたは例による問合せ(QBE)フィルタ仕様でドキュメントを検索します。

注意:

メソッドgetContentAsString()を使用する例では、コレクション内のすべてのドキュメントがJSONドキュメントであることを想定しています。そうでない場合、このメソッドは例外をスローします。

関連項目:

例1-10 コレクション内のすべてのドキュメントの検索

この例は、コレクション内の各ドキュメントを含む問合せ結果リストのカーソルを最初に取得します。次にwhile文のカーソルを使用し、結果リスト内の各ドキュメントのコンテンツを文字列として取得して出力します。最後にカーソルをクローズします。

注意:

リソース・リークを回避するには、不要なカーソルをすべてクローズします

OracleCursor c = col.find().getCursor();

while (c.hasNext()) {
  OralceDocument resultDoc = c.next();
  System.out.println("Document content: " + resultDoc.getContentAsString());
}

// IMPORTANT: You must close the cursor to release resources!
c.close;

例1-11 ドキュメント・キーを付与した一意のドキュメントの検索

この例では、OracleOperationBuilderのメソッドをつなげて、キーが"key1"の一意のドキュメントを検索する操作を指定します。非ターミナル・メソッドkey()を使用してドキュメントを指定します。次に、ターミナル・メソッドgetOne()を使用して、読取り操作を実行してドキュメントを返します(またはドキュメントが見つからない場合、nullを返します)。

OracleDocument doc = col.find().key("key1").getOne();

例1-12 ドキュメント・キーを指定した複数のドキュメントの検索

この例では、(文字列の)キー"key1""key2"および"key3"を指定して、HashSet myKeysを定義します。これらのキーを持つドキュメントを検索し、各ドキュメントのキーおよびコンテンツを出力します。

非ターミナル・メソッドkeys()では、特定のキーのドキュメントを指定します。ターミナル・メソッドgetCursor()では、読取り操作を実行し結果ドキュメントを介してカーソルを返します。

注意:

メソッドkeys()に指定されるセット内のキーの最大数は1000を超えることはできません。

Set<String> myKeys = new HashSet<String>();
myKeys.put("key1");
myKeys.put("key2");
myKeys.put("key3");
 
OracleCursor c = col.find().keys(myKeys).getCursor();
 
while (c.hasNext(()) {
  OracleDocument resultDoc = c.next();
 
  // Print the document key and document content
  System.out.println ("Document key: " + resultDoc.getKey() + "\n" +
                        " document content: " + resultDoc.getContentAsString());
}
 
c.close(); 

例1-13 フィルタ仕様によるドキュメントの検索

非ターミナル・メソッドfilter()では、コレクション内のJSONドキュメントをフィルタする強力な方法を提供します。OracleDocumentパラメータはJSONの例による問合せ(QBE、フィルタ仕様とも呼ばれる)です。

この例では、次の操作を行います。

  1. nameフィールドの値が"Alexander"のすべてのJSONドキュメントを検索するフィルタ仕様を作成します。

  2. フィルタ仕様を使用して一致するドキュメントを検索します。

  3. 各ドキュメントのキーおよびコンテンツを出力します。

// Create the filter specification
OracleDocument filterSpec =
  db.createDocumentFromString("{ /"name/" : /"Alexander/"}");
 
OracleCursor c = col.find().filter(filterSpec).getCursor();
 
while (c.hasNext(()) {
  OracleDocument resultDoc = c.next();
 
  // Print the document key and document content
  System.out.println ("Document key: " + resultDoc.getKey() + "\n" +
                        " document content: " + resultDoc.getContent());
}
 
c.close(); 

例1-14 メソッドskip()とlimit()を使用したページ区切り問合せの指定

この例では、ページ区切り問合せで非ターミナル・メソッドskip()およびlimit()を使用します。(filterSpec例1-13のフィルタ仕様です。)

// Find all documents matching the filterSpec, skip the first 1000,
// and limit the number of returned documents to 100.
OracleCursor c =
  col.find().filter(filterSpec).skip(1000).limit(100).getCursor();

while (c.hasNext(()) {
  OracleDocument resultDoc = c.next();
 
  // Print the document key and document content
  System.out.println ("Document key: " + resultDoc.getKey() + "\n" +
                        " document content: " + resultDoc.getContent());
}
 
c.close();

例1-15 ドキュメント・バージョンの指定

非ターミナル・メソッドversion()では、ドキュメント・バージョンを指定します。これは、書込み操作用のターミナル・メソッドとともに使用する場合、オプティミスティック・ロックの実装に便利です。

非ターミナル・メソッドheaderOnly()では、ドキュメント・ヘッダーのみを返すことを指定します。ドキュメント・ヘッダーには、コンテンツを除いたすべてのドキュメント・コンポーネントが含まれています。

// Find a document with key "key1" and version "version1".
OracleDocument doc = col.find().key("key1").version("version1").getOne();

例1-16 ドキュメントの検索およびヘッダーのみの戻し

この例では、指定したドキュメント・キーを持つすべてのドキュメントを検索し、そのヘッダーのみを返します。(キーはHashSet myKeysにあり、例1-12で定義されています。)

// Find all documents matching the keys in HashSet myKeys.
// For each document, return all document components except the content.
OracleCursor c = col.find().keys(myKeys).headerOnly().getCursor();

例1-17 見つかったドキュメントの数のカウント

この例では、ターミナル・メソッドcount()を使用して、コレクション内のすべてのドキュメントの数を取得します。例1-13のフィルタ仕様filterSpecによって返されるすべてのドキュメントの数を取得します。

// Get a count of all documents in the collection
int numDocs = col.find().count();
 
// Get a count of all documents in the collection that match a filter spec
numDocs = col.find().filter(filterSpec).count();

JavaのためのSODAによるコレクション内のドキュメントの置換

コレクション内のドキュメントのコンテンツを別のドキュメントのコンテンツで置き換えるには、OracleOperationBuilderのメソッドkey(String)をメソッドreplaceOne(OracleDocument)またはメソッドreplaceOneAndGet(OracleDocument)につなげます。メソッドreplaceOne(OracleDocument)はドキュメントのみを置き換えます。メソッドreplaceOneAndGet(OracleDocument)は結果ドキュメントも返します。これにはコンテンツ以外のすべてのドキュメント・コンポーネントが含まれています。

replaceOne(OracleDocument)replaceOneAndGet(OracleDocument)の両方で最終変更のタイムスタンプおよびバージョンの値を更新します。置き換えてもドキュメント・キーまたは作成時のタイムスタンプは変更されません

注意:

デフォルト・メソッドを含め、バージョンを生成する一部のメソッドでは、ドキュメント・コンテンツのハッシュ値を生成します。このような場合、ドキュメント・コンテンツが変更されないと、バージョンも変更されません。バージョンを生成するメソッドの詳細は、「カスタム・メタデータを使用したSODAコレクション構成」を参照してください。

関連項目:

例1-18 コレクション内のドキュメントの置換えおよび結果ドキュメントの取得

この例では、コレクション内のドキュメントを置き換え、結果ドキュメントを取得し、結果ドキュメントから生成したコンポーネントを取得します。

OracleDocument newDoc = ...
OracleDocument resultDoc = col.find().key("k1").replaceOneAndGet(newDoc);

if (resultDoc != null)
{
  // Get the generated document key (unchanged by replacement operation)
  String key = resultDoc.getKey();
 
  // Get the generated version
  String version = resultDoc.getVersion();
 
  // Get the generated last-modified timestamp
  String lastModified = resultDoc.getLastModified();
 
  // Get the creation timestamp (unchanged by replacement operation)
  String createdOn = resultDoc.getCreatedOn();
}

例1-19 バージョンが変更されなかった場合のみのドキュメントの置換え

ドキュメントを置き換える場合にオプティミスティック・ロックを実装するには、この例のようにメソッドkey()およびversion()をつなげることができます。

OracleDocument resultDoc = 
  col.find().key("k1").version("v1").replaceOneAndGet(newDoc);

JavaのためのSODAによるコレクションからのドキュメントの削除

コレクションからドキュメントを削除するには、(1) OracleCollectionのメソッドfind()を次のOracleOperationBuilderのメソッドにつなげます: (2) key()keys()またはfilter()、(3) version() (オプション)および(4) remove()。次に例を示します。

関連項目:

例1-20 ドキュメント・キーによるコレクションからのドキュメントの削除

この例では、ドキュメント・キーが"k1"のドキュメントを削除します。削除したドキュメントの数が返されます。

// Count is 1, if the document with key "k1" is found in the collection.
// Count is 0, otherwise.
int count = col.find().key("k1").remove();

例1-21 バージョンが変更されなかった場合のみのドキュメントの削除

ドキュメントを削除する場合にオプティミスティック・ロックを実装するには、この例のようにメソッドkey()およびversion()をつなげることができます。

col.find().key("k1").version("v1").remove();

例1-22 ドキュメント・キーによるコレクションからのドキュメントの削除

この例では、キーが"k1"および"k2"のドキュメントを削除します。

Set<String> myKeys = new HashSet<String>();
myKeys.add("k1");
myKeys.add("k2");

// Count is 2 if two documents with keys "k1" and "k2"
// were found in the collection.
int count = col.find().keys(myKeys).remove();

例1-23 フィルタによるコレクションからのJSONドキュメントの削除

この例では、フィルタを使用してgreetingフィールドの値が"hello"であるJSONドキュメントを削除します。その後、削除されたドキュメントの数を出力します。

OracleDocument filterSpec =
   db.createDocumentFromString("{ \"greeting\" : \"hello\" }");

int count = col.find().filter(filterSpec).remove();

// Print the number of documents removed
System.out.println ("Removed " + count + " documents"):

OracleOperationBuilderのターミナル・メソッドおよび非ターミナル・メソッド

OracleOperationBuilderのメソッドをつなげて、コレクションに対して読取りおよび書込み操作を指定できます。

OracleOperationBuilderでは、次の非ターミナル・メソッドを提供しています。これをつなげて読取りおよび書込み操作を指定できます: key()keys()filter()version()skip()limit()およびheaderOnly()

呼び出されたオブジェクトと同じOracleOperationBuilderオブジェクトを返し、これらのメソッドをつなげることができるため、非ターミナル・メソッドと呼ばれます。非ターミナル・メソッドは操作の一部を指定できますが、操作を作成または実行できません。

OracleOperationBuilderではターミナル・メソッドも提供しています。ターミナル・メソッドは常にメソッド・チェーンの最後に出現し、操作を作成および実行します。

読取り操作のターミナル・メソッドはgetCursor()getOne()およびcount()です。書込み操作のターミナル・メソッドはreplaceOne()replaceOneAndGet()およびremove()です。

注意:

OracleCursorのメソッドnext()またはOracleOperationBuilderのメソッドgetOne()を使用している場合で、基礎となるドキュメントが2GBを超える場合、例外がスローされます。

メソッドのJavadocドキュメントに記述がなければ、すべての非ターミナル・メソッドをつなぎ、ターミナル・メソッドでチェーンを終了できます。ただし、すべての組合せに意味があるわけではありません。たとえば、メソッドversion()key()以外のメソッドにつないだり、メソッドkey()またはkeys()をメソッドfilter()につないでも意味がありません。

表1-1では、コレクションに対する操作を構築するためのOracleOperationBuilderの非ターミナル・メソッドについて簡単に説明します。


表1-1 OracleOperationBuilderの非ターミナル・メソッド

メソッド 説明

key()

指定したドキュメント・キーを持つドキュメントを検索します。

keys()

指定した複数のドキュメント・キーを持つ複数のドキュメントを検索します。引数として渡されるキーの最大数は1000を超えることはできません。

filter()

フィルタ仕様(JSONで表される例による問合せ)と一致するドキュメントを検索します。

version()

指定したバージョンのドキュメントを検索します。通常、これはkey()とともに使用されます。たとえば、find().key("key1").version("version1")のように使用します。

headerOnly()

結果からドキュメント・コンテンツを除外します。

skip()

結果内で指定した数のドキュメントをスキップします。

limit()

結果ドキュメントの数を指定した数に制限します。


表1-2では、コレクションに対して読取り操作を作成および実行するためのOracleOperationBuilderのターミナル・メソッドについて簡単に説明します。


表1-2 読取り操作用のOracleOperationBuilderのターミナル・メソッド

メソッド 説明

getOne()

最大で1つのドキュメントを返す操作を作成および実行します。たとえば、非ターミナル・メソッドkey()の呼出しを含む操作です。

getCursor()

読取り操作の結果によってカーソルを取得します。

count()

操作で見つかったドキュメントの数をカウントします。


関連項目:

JavaのためのSODAによるフィルタ仕様(QBE)の使用

例による問合せ(QBE)とも呼ばれるフィルタ仕様は、JSONで表されるパターンを使用するSODA問合せです。問合せでは、コレクションでこれを満たすJSONドキュメントが選択されます。つまり、フィルタ仕様でそのドキュメントのみがtrueと評価されるということです。

QBEパターンでは、フィールドの存在のテスト用演算子、値比較演算子および論理演算子(論理和($or)、論理積($and)および否定($not))などのフィールドの基本演算子を含むドキュメントの選択または照合用の演算子を使用します。

注意:

異種コレクション(メディア・タイプ列を含むコレクション)でのQBEはサポートされていません。このようなコレクションは、JSONとJSON以外の両方のコンテンツの格納用に設計されています。

サンプルJSONドキュメント

サンプルJSONドキュメントのいくつかをここで示します。これらは例による問合せ(QBE)の例および参照の説明で参照されています。

例1-24 サンプルJSONドキュメント1

{ "name" : "Jason",  
  "age" : 45,   
  "address" : [ { "street" : "25 A street", 
                  "city" : "Mono Vista", 
                  "zip" : 94088,
                  "state" : "CA" } ],  
  "drinks" : "tea" }

例1-25 サンプルJSONドキュメント2

{ "name" : "Mary", 
  "age" : 50, 
  "address" : [ { "street" : "15 C street", 
                  "city" : "Mono Vista", 
                  "zip" : 97090, 
                  "state" : "OR" }, 
                { "street" : "30 ABC avenue", 
                  "city" : "Markstown",
                  "zip" : 90001, 
                  "state" : "CA" } ] }

例1-26 サンプルJSONドキュメント3

{ "name" : "Mark", 
  "age" : 65, 
  "drinks" : ["soda", "tea"] }

QBEのパスの使用

例による問合せ(QBE)にはドキュメント・フィールドへの0個以上のパスが含まれています。(QBEにおいて、"フィールドへのパス"は、非公式に"フィールド"と短縮されることがあります。)フィールドへのパスは複数のステップを含めることができ、オブジェクトと配列の両方の境界を超えることができます。

たとえば、次のQBEはzipフィールドがフィールドaddressに存在し、値が94088であるすべてのドキュメントを見つけます。

{ "address.zip" : 94088 }

前述のフィルタ仕様はサンプル・ドキュメント1と一致します。

パスは、大カッコ([および])で配列の位置を囲むことにより、JSONドキュメント内の配列の特定の要素を対象にすることができます。

たとえば、パスaddress[1].zipは、配列addressesの2番目のオブジェクト内のすべてのzipフィールドを対象にします(配列の位置番号は1ではなく、0から始まります。)次のQBEは、address配列の2番目のオブジェクトに値が90001zipフィールドが含まれているため、サンプル・ドキュメント2と一致します。

{ "address[1].zip" : 90001}

特定の配列位置を指定するかわりに、位置のリスト(例: [1,2])または位置の範囲(例: [1 to 3])を指定できます。次のQBEは、配列drinksの最初の要素(位置0)として"soda"が含まれているため、サンプル・ドキュメント3と一致します。

{ "drinks[0,1]" : "soda" }

また、次のQBEは、2番目または3番目の配列要素(位置1または2)として"soda"が含まれていないため、いずれのサンプル・ドキュメントとも一致しません。

{ "drinks[1 to 2]" : "soda" }

配列ステップを指定しない場合は、[*]が仮定されます。これはすべての配列要素と一致します。つまり、 *はワイルドカードとして機能します。たとえば、フィールドdrinksの値が配列である場合、次のQBEはいずれかの配列要素の値が文字列"tea"の場合に一致するものを見つけます。

{"drinks" : "tea"}

このQBEはサンプル・ドキュメント1および2と一致します。明示的にワイルドカードを使用する同等のQBEは、次のようになります。

{"drinks[*]" : "tea"}

QBEの基本フィールド演算子の使用

例による問合せ(QBE)の基本フィールド演算子は、指定したフィールドが指定した一連の基準を満たすかどうかをテストします。基本フィールド演算子は、$existsまたは比較演算子のいずれかです。

比較演算子は、あるフィールドの値を他の1つ以上の値と比較します。比較演算子は、$eq$ne$gt$gte$lte$startsWith$regex$in$ninおよび$allです。

最も単純で便利なフィルタ仕様の1つは、フィールドが特定の値と等しいかどうかをテストします。たとえば、次のフィルタ仕様はフィールドnameの値が"Jason"であるすべてのドキュメントを見つけます。

{ "name" : { "$eq" : "Jason" } }

QBE演算子$eqを省略すると便利です。したがって、次のスカラー等価フィルタ仕様は$eqを使用する前述のフィルタ仕様と同じです。

{ "name" : "Jason" }

前述の両方のフィルタ仕様はサンプル・ドキュメント1と一致します。

$eqはQBE比較演算子の一例です。1つのQBEフィールドの値であるオブジェクトで複数の比較演算子を組み合せることができます。

たとえば、次のQBEでは比較演算子$gt$ltを使用します。これはサンプル・ドキュメント2と一致します。このドキュメントには45より大きくて($gt) 55より小さい($lt)値(50)を持つageフィールドが含まれているためです。

{ "age" : { "$gt" : 45, "$lt" : 55 } }

関連項目:

QBE論理組合せ演算子の使用

例による問合せ(QBE)論理組合せ演算子($and$orおよび$nor)を使用し、条件を組み合せてさらに複雑なQBEを形成します。各演算子は条件の配列を引数として受け入れます。

配列引数内の各条件がドキュメントと一致する場合に、QBE論理組合せ演算子$andは一致するドキュメントを見つけます。たとえば、次のQBEはサンプル・ドキュメント1と一致します。このドキュメントに値が"Ja"で始まるフィールドname、および値が"tea"であるフィールドdrinksが含まれているためです。

{"$and" : [ {"name" : {"$startsWith" : "Ja"}}, {"drinks" : "tea"} ]}

演算子$andを省略することもできます。たとえば、次の問合せは前述の問合せと同等です。

{"name" : {"$startsWith" : "Ja"}, "drinks" : "tea"}

配列引数内の少なくとも1つの条件がドキュメントと一致する場合に、QBE論理組合せ演算子$orは一致するを見つけます。

たとえば、次のQBEはサンプル・ドキュメント2および3と一致します。これらのドキュメントにはフィールドaddressの下にフィールドzipが含まれていて、zipの値が94000未満であるか、フィールドdrinksの値が"soda"であるか、あるいはその両方であるためです。

{"$or" : [ {"address.zip" : {"$le" : 94000}}, {"drinks" : "soda"} ]}

配列引数内の条件がドキュメントと一致しない場合に、QBE論理組合せ演算子$norは一致するドキュメントとを見つけます。(演算子$norおよび$orは論理補数演算子です。)

次の問合せはサンプル・ドキュメント1と一致します。このドキュメントにはフィールドaddressの下にフィールドzipがありますが、zipの値が94000未満ではなく、値が"soda"であるフィールドdrinksもないためです。

{"$nor" : [{"address.zip" : {"$le" : 94000}}, {"drinks" : "soda"}]}

論理組合せ演算子の配列引数内の各要素は条件です。

たとえば、次の条件には演算子$andを指定した論理組合せ句が1つあります。$andの配列値には2つの条件があります。最初の条件はフィールドageの値を制限します。2番目の条件には$orを指定した論理組合せ句が1つあり、フィールドnameの値またはフィールドdrinksの値を制限します。

{ "$and" : [ { "age" : {"$gte" : 60} },
             { "$or" : [ {"name" :  "Jason"},
                         {"drinks" : {"$in" : ["tea", "soda"]}} ] } ] }
  • フィールドageの比較を含む条件はサンプル・ドキュメント3と一致します。

  • 論理組合せ演算子$orを含む条件はサンプル・ドキュメント1および3と一致します。

  • 条件全体ではサンプル・ドキュメント3のみと一致します。このドキュメントのみがageの条件と$orを使用する条件の両方を満たすドキュメントであるためです。

次の条件は、演算子$orの配列引数内に2つの条件があります。最初の条件には$andを指定した論理組合せ句が1つあり、フィールドnameおよびdrinksの値を制限します。2番目の条件には$norを指定した論理組合せ句が1つあり、フィールドageおよびnameの値を制限します。

{ "$or" : [ { "$and" : [ {"name" : "Jason"},
                         {"drinks" : {"$in" : ["tea", "soda"]}} ] },
            { "$nor" : [ {"age" : {"$lt" : 65}},
                         {"name" : "Jason"} ] } ] }
  • 演算子$andを含む条件はサンプル・ドキュメント1と一致します。

  • 演算子$norを含む条件はサンプル・ドキュメント3と一致します。

  • 条件全体ではサンプル・ドキュメント1と3の両方と一致します。これらのドキュメントがそれぞれ、$or引数内の少なくとも1つの条件を満たすためです。

論理演算子$notの使用

例による問合せ(QBE)の論理演算子$notを使用して、そのオペランドの値(単一の存在または比較基準のいずれか)を否定します。オペランドの基準がtrueの場合、$not句はfalseに評価し、基準がfalseの場合、$notはtrueに評価します。

たとえば、次のQBEではサンプル・ドキュメント1および3と一致します。ドキュメント1にはパスaddress.zipと一致するフィールドがありますが、その値は"90001"ではなく、ドキュメント3にはパスaddress.zipと一致するフィールドがありません。

{"address.zip" : {"$not" : { "$eq" : "90001" }}}

ネストした条件の使用

例による問合せ(QBE)をネストした条件とともに使用して、オブジェクト要素を含む配列値のフィールドを持つドキュメントを見つけることができます。ここでは、配列の特定のオブジェクトは複数の基準を満たします。

次の条件は、配列addressの下の同じオブジェクトcity値が"Mono Vista"state値が"CA"のドキュメントを見つけます。

{"address" : { "city" : "Mono Vista", "state" : "CA"}}

これは、親フィールドaddressが必要であることを示します。そのフィールドの値が配列の場合、配列内の少なくとも1つのオブジェクトに、値が"Mono Vista"cityフィールドおよび値が"CA"stateフィールドが必要です。3つのサンプル・ドキュメントのうち、このQBEはサンプル・ドキュメント1のみと一致します。

次のQBEもサンプル・ドキュメント1と一致しますが、サンプル・ドキュメント2とも一致します。

{"address.city" : "Mono Vista", "address.state" : "CA"}

前述のQBEとは異なり、ここではcityとstateが同じアドレスに属する必要があるという制限がありません。かわりに、このQBEでは、一致するドキュメントにaddress配列のオブジェクトに値が"Mono Vista"cityフィールドおよびaddress配列のオブジェクトに値が"CA"stateフィールドが必要であることのみを指定します。フィールドaddress.cityおよびaddress.stateが同じオブジェクトに存在する必要があることを指定しているわけではありません。

QBE演算子$idの使用

通常、他の例による問合せ(QBE)の演算子はドキュメント内で特定のJSONフィールドを検索し、その値を照合しようとします。かわりに、演算子$idはドキュメント・キーと照合します。QBEの最も外側の条件で演算子$idを使用します。

例1-27に、$idを使用する3つのQBEを示します。

注意:

JavaのためのSODAのQBEで$id条件を使用する代替手段として、OracleOperatorBuildのメソッドkey()またはkeys()を使用して、メソッドfilter()と組み合せてドキュメント・キーを指定できます。

例1-27 $idを使用した特定のキーを持つドキュメントの検索

// Find the unique document that has key "key1".
{"$id" : "key1"}

// Find the documents that have any of the keys "key1", "key2", and "key3".
{"$id" : ["key1","key2","key3"]}

// Find the documents that have at least one of the keys "key1" and "key2",
// and that have an object with a field address.zip whose value is at least 94000.
{"$and" : [{$id : ["key1", "key2"]},
           {"address.zip" : { "$gte" : 94000 }}]}

QBE演算子$orderbyの使用

例による問合せ(QBE)の演算子$orderbyについて説明します。

これは問合せ結果を昇順または降順にソートします。

次のQBEでは、フィールドageおよびsalaryの順序を指定します。値に1を指定すると、ageを昇順にソートします。値に-2を指定すると、salaryを降順にソートします。1の絶対値は-2の絶対値よりも小さいため、agesalaryの順にソートされます。

{ "$query" : { "age" : { "$gt" :  40 } },
  "$orderby" :  { "age" : 1, "salary" : -2 } }

フィルタ仕様で演算子$orderbyを1つ以上のフィルタ条件とともに使用した場合、これらの条件を演算子$queryでラップする必要があります。前述の問合せで、返されるドキュメントは、フィールドageの値が40より大きい値である必要があることを指定したフィルタ条件を満たすドキュメントに限定されます。

フィルタ仕様による問合せ

特定のフィルタ仕様(例による問合せ(QBE))と一致するドキュメントのコレクションを問い合せることができます。これを実行するには、QBEを表すJSON OracleDocumentをメソッドOracleOperationBuilder filter()に渡します。

例1-28に、これを示します。

例1-28 フィルタ仕様の実行

OracleDatabase db = ...
 
// OracleCollection - assume it is empty
OracleCollection col = ...
 
// Insert into the collection a document with field "name" set to "Jason"
// and field "location" set to "California".
OracleDocument doc =
   db.createDocumentFromString("{\"name\" : \"Jason\",
                                  \"location\" : \"California\"}");
col.insert(doc);
 
// Insert another document into the collection with field "name" set to "Mary",
// and field "location" set to "California".
doc = db.createDocumentFromString("{\"name\" : \"Mary\",
                                     \"location\" : \"California\"}");
col.insert(doc);
 
// Create a filter specification for matching all documents with
// the field "name" set to "Jason"
OracleDocument filterSpec =
   db.createDocumentFromString("{\"name\" : \"Jason\"}");
 
// Run the filter specification
OracleCursor c = col.find().filter(filterSpec).getCursor();
 
// The cursor returns a single document with this content:
// { "name" : "Json", "location" : "California" } --
// the first document inserted above.
 
while (c.hasNext())
{
     OracleDocument c = c.next();
}
 
c.close();

SODAのパス

SODAの仕様にはパスが含まれており、それぞれがJSONドキュメントの値を対象とします。パスは、一連のステップで構成されます。

注意:

パスでは、厳密なJSON構文を使用する必要があります。つまり、すべての数値以外の値を二重引用符(")で囲む必要があります。厳密なJSON構文と緩慢なJSON構文の詳細は、『Oracle Database JSON開発者ガイド』を参照してください。

パス・ステップで使用される文字には、2種類(構文の文字と使用可能な文字)あります。構文の文字には、JSON用の特別な構文の意味があります。次のものがあります。

  • ピリオド(.)は、親オブジェクトのフィールド名と子オブジェクトのフィールド名を分離します。

  • カッコ([および])は、配列の区切り文字です。

  • カンマ(,)は、配列要素またはインデックス・コンポーネントを分離します。

  • ワイルドカード(*)は、プレースホルダです。配列ステップのインデックスとフィールド・ステップのフィールド名を一致させます。

使用可能な文字は、構文の文字ではない文字です。

パスには、2種類のステップ(フィールド・ステップと配列ステップ)があります。

フィールド・ステップは、次のいずれかです。

  • ワイルドカード文字* (単独で)

  • 一連の使用可能な文字 - たとえば、cat

  • バッククォート文字で囲まれた一連の文字(使用可能または構文) (`) - たとえば、`dog`および`cat*dog`

バッククォート文字で囲まれているフィールド・ステップ内では、構文の文字は構文的には機能せず、通常の文字として文字どおりに処理されます。構文の文字を文字どおりに処理する場合は、構文の文字を含むフィールド・ステップを、バッククォート文字のペアで囲む必要があります。

dogのすべての文字は許可されており、`dog`のバッククォート文字はオプションです。次の各フィールド・ステップには構文の文字が含まれているため、バッククォート文字で囲む必要があります。

`cat.dog`
`cat[dog]`
`cat,dog`
`cat*dog`

`cat*dog`では、アスタリスクはワイルドカードとして機能しません。これはバッククォートによってエスケープされているため、通常の文字として機能します。ただし、パス{ "*.b" : 42 }内では、エスケープされていないアスタリスクはワイルドカードとして機能し、フィールド名のプレースホルダになります。同様に、エスケープされていないピリオドも構文的に機能します。

バッククォート文字で囲んだステップにバッククォート文字が含まれている場合は、連続した2つのバッククォート文字を使用してその文字を表す必要があります。たとえば、`Customer``s Comment`のようになります。

ピリオド(.)には、フィールド・ステップが続く必要があります。パスの最初のステップの後、各フィールド・ステップの前にはピリオドが必要です。

配列ステップは、カッコ([および])で区切られています。カッコの中は次のいずれかです。

  • ワイルドカード文字* (単独で)

  • 1つ以上の次のインデックス・コンポーネント:

    • ゼロ以上の整数である単一のインデックス

    • 次の構文によるインデックスの範囲:

      x to y
      

      xおよびyはゼロ以上の整数で、xy以下です。xtoの間、およびtoyの間には、少なくとも1つの空白文字が必要です。

    複数のコンポーネントは、カンマ(,)で区切る必要があります。複数のコンポーネントのリストでは、インデックスは昇順である必要があり、範囲は重複できません。

たとえば、次のものは有効な配列ステップです。

[*]
[1]
[1,2,3]
[1 to 3]
[1, 3 to 5]

次のものは有効な配列ステップではありません

[*, 6]
[3, 2, 1]
[3 to 1]
[1 to 3, 2 to 4]

SODAフィルタ仕様(QBE)

パターン一致によってコレクション内のJSONドキュメントを選択できます。

フィルタ仕様例による問合せ(QBE)または簡潔にフィルタ,とも呼ばれ、JSONで表されるパターンを使用するSODA問合せです。一部のSODA操作はフィルタ仕様を使用して、コレクション内でこれを満たすすべてのJSONドキュメントを選択します。つまり、フィルタ仕様ではそのコレクションのこれらのオブジェクトのみに対してtrueと評価されるということです。したがって、フィルタ仕様ではこれを満たすドキュメントの特性を指定します。

フィルタ仕様のパターンではQBE演算子を使用します。これは、名前が$で始まる、事前定義済のJSONフィールドです。演算子のJSON値はオペランドまたは引数脚注1と呼ばれます。

SODA演算子自体はJSONフィールドですが、フィルタ仕様の説明として簡単に言うと、フィールドという用語は、ここではSODA演算子ではないJSONフィールドのことです。(QBEにおいて、"フィールド"は非公式に"フィールドへのパス"として使用されることがあります。)

注意:

フィルタ仕様では、厳密なJSON構文を使用する必要があります。つまり、すべての数値以外の値を二重引用符で囲む必要があります。これにはQBE演算子が含まれています。厳密なJSON構文と緩慢なJSON構文の詳細は、『Oracle Database JSON開発者ガイド』を参照してください。

フィルタ仕様はJSONオブジェクトです。フィルタ仕様には3種類あります。

  • 空のフィルタ: { }。空のフィルタは、コレクション内のすべてのオブジェクトに一致します。

  • 複合フィルタ。

  • フィルタ条件フィルタ。

フィルタ仕様(QBE)は問合せの最上位(ルート)レベルでのみ指定できます。ただし、フィルタ条件はフィルタ条件フィルタ(QBE)として単独で使用することも、下位レベルで複合フィルタの問合せ句で使用することもできます。

注意:

異種コレクション(メディア・タイプ列を含むコレクション)でのQBEはサポートされていません。このようなコレクションは、JSONとJSON以外のコンテンツの格納用に設計されています。

複合フィルタ

複合フィルタ仕様(例による問合せ、QBE)は最上位レベルでのみ指定できます。つまり、別の複合フィルタの内側またはフィルタ条件の内側に複合フィルタをネストできません。

複合フィルタは、次の句の1つまたは両方から構成されます。

どちらの句も複数回は使用できません。

次の複合フィルタには両方の句が含まれています。

{ "$query" : { "salary" : { "gt" : 10000 } },
  "$orderby" : { "age" : -1, "zipcode" : 2 } } }

この例で、問合せ句では値が10,000より大きいsalaryフィールドを持つドキュメントを選択し、orderby句では選択したドキュメントを最初にageの降順で次にzip codeの昇順でソートします。

Orderby句による選択したオブジェクトのソート

orderby句を含むフィルタ仕様(例による問合せ、QBE)では選択したJSONドキュメントをソートして返します。

次に、orderby句の構文を示します。

"$orderby" : { field1 : direction1, field2 : direction2, ... }

演算子$orderbyの値は、1つ以上のメンバーを含むJSONオブジェクトです。

fieldは、候補オブジェクトのルートからのパスとして解釈される文字列です。

directionはゼロ以外の整数です。これは、返されるドキュメントをfield値をキーにして、値が正数か負数かに応じてそれぞれ昇順または降順にソートします。

$orderbyオペランドのフィールドは絶対値の小さい順にソートされます。たとえば、値が-1のフィールド、値が2のフィールド、値が3のフィールドの順にソートされます。

次のフィルタ仕様では、フィールドsalaryの値が10,000より大きく20,000以下であるオブジェクトを選択します。これは最初にageをキーとして降順に、次にzipcodeをキーとして昇順にオブジェクトをソートします。

{ "$query"   : { "salary" : { "$gt" : 10000, "$lte" : 20000 } },
  "$orderby" : { "age" : -1, "zipcode" : 2 } }

次のSQL SELECT文の抜粋と類似しています。

WHERE (salary > 10000) AND (salary <= 20000)
ORDER BY age DESC, zipcode ASC

2つ以上のソート方向の絶対値が等しい場合、フィールドのソート順序は、JSONドキュメントの作成に使用したシリアライズ済JSONコンテンツに出現する順序で決定されます。

特に外部ツールまたはライブラリを使用してJSONコンテンツを作成し、結果のコンテンツがシリアライズされる順序が不明な場合、フィールドが使用される順序を正確に制御するために、絶対値が等しくないソート方向を使用することをお薦めします。

関連項目:

パス文字列の詳細は、「SODAのパス」,を参照してください

フィルタ条件

フィルタ条件はフィルタ仕様として単独で使用することも、下位レベルで複合フィルタ仕様の問合せ句で使用することもできます。

フィルタ条件は単に条件と呼ばれることがあり、次のような1つ以上の句から構成されます。

フィルタ条件は、そのすべての句がtrueの場合にのみtrueになります。フィルタ条件は空にはできません。

基本フィールド句

基本フィールド句では、特定のフィールドが特定の基準セットを満たす必要があることを指定します。

次の書式をとることができます。

  • 存在句: 存在基準が後に続くフィールド脚注2。これは演算子$existsの後にオペランド(引数)、スカラーが続くJSONオブジェクト。JSONスカラーはオブジェクトまたは配列以外の値であり、JSON数値、文字列、truefalseまたはnullです。

    存在句では、フィールドが存在するかどうかをテストします。次のうちのいずれかがtrueとなるドキュメントを見つけます。

    • フィールドが存在し、オペランドがfalsenullまたは0以外のスカラー値である。

    • フィールドが存在せず、オペランドがfalsenullまたは0である。

    たとえば、この存在句ではフィールドaddress.zipが含まれるドキュメントが存在するかどうかをテストします。

    "address.zip" : { "$exists" : true }
    
  • スカラー等価句: スカラー値が後に続くフィールド。

    スカラー等価句では、フィールドの値がスカラー値と等しいかどうかをテストします。これは、$eqを使用して同じ値をテストする同じフィールドの比較句と同等です。

    たとえば、次のスカラー等価句ではフィールドsalaryの値が10000かどうかをテストします。

    "salary" : 10000
    

    これは、次の比較句と同等です。

    "salary" : { "$eq" : 10000 }
    
  • 比較句: 1つ以上の比較基準を含むJSONオブジェクトが後に続くフィールド。比較基準はオペランドが後に続く比較演算子です。(演算子がJSONフィールド名として表示され、フィールドの値がオペランドです。)

    比較演算子は、$eq$ne$gt$lt$gte$lte$startsWith$regex$in$ninおよび$allです。

    比較句では、フィールドの値がすべての比較基準を満たすかどうかをテストします。

    たとえば、次の比較句には2つの基準があります。最初の基準はフィールドageが18より大きいかどうかをテストし、2番目の基準はそれが45以下かどうかをテストします。

    "age" : { "$gt" : 18, "$lte" : 45 }
    

表1-3に、比較演算子を示します。例の列で使用されるドキュメントについては、「サンプルJSONドキュメント」を参照してください。

表1-3 例による問合せ(QBE)の比較演算子

演算子 説明 オペランド

$eq

フィールドの値が引数の値と等しいドキュメントを見つけます。

JSONスカラー。

{"name" : { "$eq" : "Jason" }}

サンプル・ドキュメント1と一致します。

$ne

フィールドの値が引数の値と等しくないか、ドキュメント内にこのようなフィールドがないドキュメントを見つけます。

JSONスカラー。

{"name" : { "$ne" : "Jason" }}

サンプル・ドキュメント2および3と一致します。

$gt

フィールドの値が引数の値より大きいドキュメントを見つけます。

JSON数値または文字列。

{"age" : { "$gt" : 45 }}

サンプル・ドキュメント2と一致します。

$lt

フィールドの値が引数の値より小さいドキュメントを見つけます。

JSON数値または文字列。

{"age" : { "$lt" : 50 }}

サンプル・ドキュメント1と一致します。

$gte

フィールドの値が引数の値以上のドキュメントを見つけます。

JSON数値または文字列。

{"age" : { "$gte" : 45 }}

サンプル・ドキュメント1、2および3と一致します。

$lte

フィールドの値が引数の値以下のドキュメントを見つけます。

JSON数値または文字列。

{"age" : { "$lte" : 45 }}

サンプル・ドキュメント1と一致します。

$startsWith

フィールドの値が引数の値で始まるドキュメントを見つけます。

JSON文字列。

{"name" : {"$startsWith" : "J"}}

サンプル・ドキュメント1と一致します。

$regex

フィールドの値が引数の正規表現と一致するドキュメントを見つけます。

JSON文字列としてSQL正規表現。

『Oracle Database SQL言語リファレンス』を参照してください。

{"name" : { "$regex" : ".*son"}}

サンプル・ドキュメント1と一致します。

$in

フィールドが存在し、その値が引数配列の少なくとも1つの値と等しいドキュメントを見つけます。

空ではない、スカラーのJSON配列。脚注3

{"address.zip" : { "$in" : [ 94088, 90001 ] }}

サンプル・ドキュメント1および2と一致します。

$nin

次のうちのいずれかがtrueとなるドキュメントを見つけます。

  • フィールドが存在するが、その値が引数配列のどの値とも等しくない。

  • フィールドが存在しない。

空ではない、スカラーのJSON配列。脚注

{"address.zip" : { "$nin" : [ 90001 ] }}

サンプル・ドキュメント1および2と一致します。

$all

次のうちのいずれかがtrueとなるドキュメントを見つけます。

  • フィールドの値が引数配列内のすべての値を含む配列である。

  • フィールドの値がスカラー値であり、一致する値が引数配列に1つ含まれている。

空ではない、スカラーのJSON配列。脚注

{"drinks" : { "$all" : ["soda", "tea"]}}

サンプル・ドキュメント2と一致します。

{"drinks": { "$all" : ["tea"]}}

サンプル・ドキュメント1および2と一致します。

脚注3

配列に少なくとも1つの要素が含まれていない場合、構文エラーが発生します。

注意:

配列ステップで終わらないパスが比較演算子または比較句に適用される$notを使用し、パスが配列を対象とする場合、テストは配列の要素に適用されます。

たとえば、"cat"が配列要素であっても、QBE {"animal" : {"$eq" : "cat"}}はJSONデータ{"animal" : ["dog", "cat"]}と一致します。QBE {"animal" : {$not : {"$eq" : "frog"}}}は同じデータと一致します。これは、各配列要素が"frog"と等しいかどうかがテストされ、このテストが失敗するためです。(演算子$notの詳細は、論理句を参照してください。)

論理句

論理句$not句または論理組合せ句のいずれかです。

  • $not句は、オペランドが後に続く演算子$notを含むJSONオブジェクトが後に続きます。$notのオペランドは単一の存在基準または比較基準です。

    $not句は$notオペランドの値を論理的に否定します。オペランドの基準がtrueの場合、$not句はfalseに評価し、基準がfalseの場合、$notはtrueに評価します。

    たとえば、次の$not句は、フィールドaddress.zipが存在しないドキュメント、およびこのフィールドは存在するが値が"90001"以外のスカラーまたは"90001"に等しい要素がない配列であるドキュメントを見つけます。

    "address.zip" : {"$not" : { "$eq" : "90001" }}
    

    一方、次の比較句では補完的な結果になります。つまり、フィールドaddress.zipが存在し、その値がスカラー"90001"またはスカラー値を含む配列のドキュメントを見つけます。

    "address.zip" : { "$eq" : "90001"}}
    
  • 論理組合せ句論理演算子($and$orまたは$nor)であり、空でない配列の1つ以上のフィルタ条件が後に続きます。脚注4

    この論理組合せ句は演算子$orを使用します。

    "$or" [ { "name" : "Joe" }, { "salary" : 10000 } ]
    

    次の論理組合せ句は演算子$andを使用します。配列オペランドにはメンバーとして2つのフィルタ条件があります。これらの句の2番目は演算子$orを使用する論理組合せ句を含む条件です。

    "$and" : [ {"age" : {"$gte" : 60}},
               {"$or" : [{"name" : "Jason"}, {"drinks" : "tea"}]} ]
$andの省略

$andの使用を省略することもできます。

フィルタ条件は、そのすべての句がtrueの場合にのみtrueになります。また、比較句は、複数の比較基準を含むことができ、比較が全体としてtrueとなるには、そのすべてがtrueとなる必要があります。これらの基準のそれぞれにおいて、論理積(AND)は暗黙的になります。したがって、$andの使用を省略して簡潔にできます。

これについては例1-29および例1-30に示しています。これらは結果が同じになります。演算子$andは、例1-29では明示的であり、例1-30では暗黙的(省略されています)です。

このフィルタは、nameが「Fred」で始まり、かつsalaryが10,000より大きく20,000以下で、かつaddress.cityが「Bedrock」またはaddress.zipcodeが12345で、かつmarriedtrueのオブジェクトを指定します。

$andの省略の概要は次のとおりです: $andを省略した場合、結果フィルタのフィールドまたは演算子が同じオブジェクトの同じレベルで複数回出現しないようにします。

このルールでは、次のようにQBEを使用することはできません。ここでは、フィールドsalaryが同じオブジェクトの同じレベルで2回出現します。

{ "salary" : { "$gt" : 10000 }, "age" : { "$gt" : 40 }, "salary" : { "$lt" : 20000 } }

また、次のようにQBEを使用することもできません。ここでは、同じ比較演算子$regexが同じ比較でフィールドnameに複数回適用されています。

{ "name" : { "$regex" : "son", "$regex" : "Jas" } }

ここでの動作は、両方の$regex基準がtrueの場合かつその場合にかぎり、フィールドの条件はtrueになりません。そのように動作させるには、次のようなQBEを使用します。

{ $and : [ { "name" : { "$regex" : "son" }, { "name" : { "$regex" : "Jas" } ] }

$andの省略の概要ルールに従わない場合、同じフィールドまたは演算子を使用する競合する条件または基準のいずれか1つのみが評価されてもう一方が無視され、エラーは発生しません。salaryの例の場合、salary比較句のいずれか1つのみが評価され、nameの例では、$regex基準のいずれか1つのみが評価されます。複数の条件または基準セットのどれが評価されるかは定義されていません。

例1-29 明示的な$and演算子を使用したフィルタ仕様

{ "$and" : [ { "name"    : { "$startsWith" : "Fred" } },
             { "salary"  : { "$gt"  : 10000, "$lte" : 20000 } },
             { "$or"     : [ { "address.city"    : "Bedrock" },
                             { "address.zipcode" : 12345 } ] },
             { "married" : true } ] }

例1-30 暗黙的な$and演算子を使用したフィルタ仕様

{ "name"    : { "$startsWith" : "Fred" },
  "salary"  : { "$gt"  : 10000, "$lte" : 20000 },
  "$or"     : [ { "address.city"    : "Bedrock" },
                { "address.zipcode" : 12345 } ],
  "married" : true }

ネストされた条件句

ネストされた条件句は親フィールドとその後に続く単一の条件から構成されます。条件に含まれているすべてのフィールドは親フィールドを対象としています。

parent_field : condition

注意:

ネストされた条件句の条件の後にフィールドが続くので、特殊な基準句を含むことはできません。後者はルート・レベルでしか発生しません。

たとえば、フィールドaddressに子フィールドのcitystateがあるとします。次のネストされた条件句は、address.cityフィールドに値"Boston"が含まれ、address.state"MA"の値が含まれているかどうかをテストします。

"address" : { "city" : "Boston", "state" : "MA" }

同様に、次のネストされた条件句は、address.cityの値がBosで始まり、address.state"MA"の値が含まれているかどうかをテストします。

"address" : { "city" : { "$startsWith : "Bos" }, "state" : "MA" }

次のドキュメントがあるとします。

{ "address" : [ { "city" : "Boston", "state" : "MA" },
                { "city" : "Los Angeles", "state" : "CA" } ] }

次の問合せではドキュメント内の各パスを個別に照合します。address配列の各オブジェクト要素を個別に照合して、cityの値が"Boston"であるか、stateの値が"CA"であるかを確認します。

{ "address.city" : "Boston", "address.state" : "CA" }

この問合せはネストされた条件がないため、cityが"Boston"でstateが"CA"単一オブジェクトのない、前述のドキュメントと一致します。

親フィールドaddressにネストされた条件を持つ次の問合せでは、前述のドキュメントと一致しません。このドキュメントには、"Boston"の値を持つフィールドcityおよび"CA"の値を持つフィールドstateの両方を含むaddress配列の単一オブジェクトが存在しないためです。

{ "address" : { "city" : "Boston", "state" : "CA" } }

関連項目:

特殊基準句

特殊基準句

特殊基準句は、ルート・レベルの条件、つまり複合フィルタまたはフィルタ条件フィルタで使用される条件でのみ使用します。

現在、特殊基準句はID句のみです。

ID句

通常、他の例による問合せ(QBE)の演算子はドキュメント内で特定のJSONフィールドを検索し、その値を照合しようとします。かわりに、演算子$idを使用するID句はドキュメント・キーを照合します。

ドキュメント・キーが指定されたドキュメントを一意に識別します。これは、作成時のタイムスタンプ、最終変更のタイムスタンプおよびバージョンなどのメタデータです。全体としてドキュメントに付属しているものですが、ドキュメント・コンテンツの一部ではありません。

ID句の構文は、QBE演算子$idの後にスカラー・キー(ドキュメントID)または空でない配列のスカラー・キーが続きます。脚注5スカラー・キーは整数または文字列である必要があります。配列要素は、すべて整数か、またはすべて文字列のいずれかでなければなりません。次に例を示します。

"$id" : "USA"
"$id" : [1001,1002,1003]

演算子$idを使用できるのは、QBEの最も外側の条件でのみです。さらに正確に言うと、QBEで他の演算子と$idも使用する場合、最も外側の条件は演算子$andであり、$id条件は一度だけ指定し、その$andの指定に対して配列引数の要素である必要があります。

例1-31に、これを示します。これは、少なくとも1つがキーkey1またはkey2を持ち、値が"red"colorフィールドを持つドキュメントを見つけます。

例1-31 最も外側のQBE条件における演算子$idの使用

{ "$and" : [ { $id : [ "key1", "key2" ] }, { "color" : "red" } ] }

SODAコレクションのメタデータ・キャッシング

SODAコレクション・メタデータは、コレクション・データと同様にデータベース内に永続的に格納されます。必要に応じて、透過的にフェッチされコレクション操作を実行します。データベースからメタデータをフェッチすると、パフォーマンス上のコストが発生します。クライアントでコレクション・メタデータをキャッシュして、メタデータを取得するためのデータベース・アクセスを回避することにより、パフォーマンスを改善できます。

コレクション・メタデータのキャッシングを使用する主な事例は次のとおりです。

  • コレクションをリストし、リストされたコレクションを1つ以上オープンする。

  • コレクションを作成してから、これをオープンする。

  • コレクションを再度オープンする。

これらのすべての事例において、キャッシュされたメタデータを使用してコレクションをオープンできます。

コレクション・メタデータのキャッシュは、特定のOracleRDBMSClientオブジェクトから取得されるすべてのOracleDatabaseオブジェクトで共有することも、単一のOracleDatabaseオブジェクトに対してローカルにすることもできます。両方の種類のキャッシングがデフォルトでは無効になっています。

ローカルと共有の両方のキャッシュが同じOracleDatabaseオブジェクトで有効になっている場合、エントリでは次のようにプロセスを参照します。

  1. ローカル・キャッシュは、データベース・オブジェクトで使用される特定のコレクションに関するエントリに対してチェックされます。

  2. ローカル・キャッシュで見つからない場合、共有キャッシュがコレクションのエントリに対してチェックされます。

  3. コレクションのエントリがキャッシュに見つからない場合、データベースにアクセスしてそのメタデータを取得しようとします。

コレクション・メタデータ・キャッシングの有効化

コレクション・メタデータ・キャッシングはデフォルトでは無効になっています。コンストラクタOracleRDBMSClient(Properties props)を使用して、共有またはローカル・コレクション・メタデータ・キャッシングを有効にできます。

ここで、パラメータpropsは、次のプロパティの1つまたは両方で初期化するPropertiesインスタンスです。

  • 値が"true"のプロパティoracle.soda.sharedMetadataCache: 共有キャッシュを有効にします

  • 値が"true"のプロパティoracle.soda.localMetadataCache: ローカル・キャッシュを有効にします

例1-32に、これを示します。共有キャッシングとローカル・キャッシングの両方を有効にします。

例1-32 コレクション・メタデータ・キャッシングの有効化

Properties props = new Properties();
props.put("oracle.soda.sharedMetadataCache", "true");
props.put("oracle.soda.localMetadataCache", "true");
OracleRDBMSClient cl = new OracleRDBMSClient(props);

コレクション・メタデータの共有キャッシュ

各SODAクライアント(OracleRDBMSClientオブジェクト)は、そのクライアントから作成されたすべてのOracleDatabaseオブジェクトに作成されたすべてのコレクション(OracleCollectionオブジェクト)のメタデータを記録するコレクション・メタデータ・キャッシュに、任意に関連付けられています。関連付けられているクライアントが解放されたときに、キャッシュが解放されます。

共有キャッシュのエントリ数は10,000エントリ(スキーマごとに100データベース・スキーマ×100コレクション)に制限されています。共有キャッシュは最も長い間使用されていない(LRU)置換ポリシーを使用します。最も長い間使用されていないエントリは、キャッシュがいっぱいのとき(エントリが10,000個あるとき)新規エントリの追加により置き換えられます。

共有メタデータのキャッシュは、アクセスの競合を回避するためにロックが必要です。並行処理を制限しているためにパフォーマンスに悪影響を及ぼす可能性があります。

ローカル・コレクション・メタデータ・キャッシュ

OracleDatabaseオブジェクトは、ローカル・コレクション・メタデータ・キャッシュに任意で関連付けられています。これは、OracleDatabaseオブジェクトに作成されたコレクションのメタデータのみを記録します。関連付けられているOracleDatabaseオブジェクトが解放されると、ローカル・キャッシュが解放されます。

ローカル・キャッシュのエントリ数には制限がなく、エントリが削除されることはありません。エントリ数は、新しいコレクションが特定のデータベース・オブジェクトに作成されると増加し続けます。

ローカル・メタデータ・キャッシュに削除ポリシーがないということは、キャッシュされたコレクション・メタデータは常に使用可能であり、メタデータがキャッシュされると、これを取得するためにデータベースにアクセスする必要がないということです。

ローカル・キャッシングには共有がないため、同じコレクションへのアクセスに異なるデータベース・オブジェクトを使用すると、共有キャッシングの場合よりもラウンド・トリップおよびデータ・レプリケーションが増加します。

共有メタデータ・キャッシュと異なり、ローカル・キャッシュではロックが必要ありません。

注意:

ローカル・キャッシュのエントリ数には制限がないので、特定のOracle Databaseオブジェクトを使用して多数のコレクションを作成する場合にはローカル・キャッシュの使用をお薦めしません。メモリーが不足する可能性があるためです。

カスタム・メタデータを使用したSODAコレクション構成

SODAコレクションは高度な構成が可能です。デフォルトで提供されているメタデータと異なるカスタム・メタデータを使用できます。

ただし、特別な理由がなくカスタム・メタデータを使用することはお薦めしません。これを行うには、SQLデータ型など、Oracle Databaseの概念を理解している必要があります(『Oracle Database SQL言語リファレンス』を参照)。SODAコレクションはOracle Database表(またはビュー)の最上位に実装されます。したがって、多数のコレクション構成コンポーネントが基礎となる表構成に関連しています。

カスタム・メタデータを使用する理由は、次のとおりです。

  • SecureFiles LOB記憶域を構成するため。

  • JSON (異種コレクション)以外のドキュメントを格納するようにコレクションを構成するため。

  • 既存のOracle RDBMS表またはビューを新規コレクションにマップするため。

  • 既存の表へのコレクションのマッピングが読取り専用であることを指定するため。

  • VARCHAR2列をJSONコンテンツに使用するため、および列に許可されているデータのデフォルトの最大長を増やすため。

    データベースが拡張データ型で構成されていて、これらのデータ型の最大長が32767バイトに拡張されている場合に、許可されている最大データ長を増やす必要があります。拡張データ型の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

コレクションを作成するために2つの方法がインタフェースOracleDatabaseAdminで使用できます(OracleDatabaseオブジェクトでメソッドadmin()を呼び出してアクセスされます)。

createCollection(String collectionName);
createCollection(String collectionName, OracleDocument collectionMetadata);

最初の方法は、引数を1つのみ使用し、デフォルトのメタデータでコレクションを作成します。デフォルト・メタデータでは、データベース・スキーマ名、表名(コレクションを格納する表の場合)、5つの表列(キー、コンテンツ、バージョン、最終変更のタイムスタンプおよび作成時のタイムスタンプ)およびこれらの表列の詳細を指定します。各表列はJSONオブジェクトを持つフィールドによって値として表されます。このオブジェクトには、名前、SQL型などの列に関するその他の詳細が含まれています。(例1-33を参照してください。)

2つ目の方法は、2つの引数を使用し、JSON OracleDocumentオブジェクトの書式でカスタム・コレクション・メタデータを指定します。

既存コレクションのメタデータの取得

OracleCollectionAdminのメソッドgetMetadata()は、コレクションにJSONメタデータ・ドキュメントを返します。

collectionName.admin().getMetadata();

例1-33に、OracleDatabaseAdminのメソッドcreateCollection(String collectionName)を使用して作成された、デフォルト構成のコレクションにメタデータ・ドキュメントでメソッドgetContentAsString()をコールした結果を示します。

例1-33 デフォルト構成のコレクションへのgetMetadataの出力

{
   "schemaName" : "mySchemaName",
   "tableName" : "myTableName",
   "keyColumn" :
   {
      "name" : "ID",
      "sqlType" : "VARCHAR2",
      "maxLength" : 255,
      "assignmentMethod" : "UUID"
   },
   "contentColumn" :
   {
      "name" : "JSON_DOCUMENT",
      "sqlType" : "BLOB",
      "compress" : "NONE",
      "cache" : true,
      "encrypt" : "NONE",
      "validation" : "STRICT"
   },
   "versionColumn" :
   {
     "name" : "VERSION",
     "type":"String",
     "method":"SHA256"
   },
   "lastModifiedColumn" :
   {
     "name":"LAST_MODIFIED"
   },
   "creationTimeColumn":
   {
      "name":"CREATED_ON"
   },
   "readOnly":false
}

コレクションに対するカスタム・メタデータの作成

コレクション・メタデータはJSON OracleDocumentインスタンスとして表されます。このようなインスタンスは直接作成できますが、かわりにOracleRDBMSMetadataBuilderを使用することをお薦めします。これは、OracleRDBMSClientのメソッドcreateMetadataBuilder()を呼び出して取得します。

メソッドcreateMetadataBuilder()では、デフォルト・コレクション・メタデータとともに事前ロードされたOracleRDBMSMetadataBuilderインスタンスを返します。この事前ロードされたメタデータを変更するには、カスタム・メタデータを作成するOracleRDBMSMetadataBuilderのメソッドをコールします。

これらのメソッドは様々なコレクション・メタデータ・コンポーネントに対応しています。これらのコンポーネントをカスタマイズするには、ビルダー・メソッドをチェーン方式で呼び出します。チェーンの最後にメソッドbuild()を呼び出してコレクション・メタデータをJSON OracleDocumentオブジェクトとして作成します。

例1-34に、これを示します。ここでは、OracleRDBMSMetadataBuilderを使用して、カスタム・メタデータ(作成時刻なし、メディア・タイプ列およびデフォルトではないバージョン列メソッド)を含むコレクションを作成します。最初に、メソッドcreateMetadataBuilder()を使用してメタデータ・ビルダー・オブジェクトを作成します。次に、このオブジェクト上でビルダー・メソッドを呼び出して使用する特定のメタデータを定義し、build()を起動してそのメタデータでcollectionMetadataオブジェクトを作成します。最後に、このメタデータを含む新規コレクションを作成します。

この場合、指定したメタデータおよびこれを定義するメソッドは、次のとおりです。


メソッド メタデータ

creationTimeColumnName()

作成時のタイムスタンプ列はありません。デフォルトで、この列は存在します。ここでは、null値によってこの列がないことが示されます。

mediaTypeColumnName()

メディア・タイプ列はMY_MEDIA_TYPE_COLUMNという名前になります。デフォルトでは、メディア・タイプ列はありません。

versionColumnMethod()

バージョン列メソッドはデフォルトのメソッドSHA256ではなく、UUIDになります。


例1-34 カスタム・メタデータが含まれるコレクションの作成

OracleRDBMSClient cl = new OracleRDBMSClient();
OracleRDBMSMetadataBuilder b = cl.createMetadataBuilder();
OracleDatabase db = cl.getDatabase(jdbcConnection);
 
// Create custom metadata
OracleDocument collectionMetadata = b.creationTimeColumnName(null).
                                      mediaTypeColumnName("MY_MEDIA_TYPE_COLUMN").
                                      versionColumnMethod("UUID").
                                      build();
 
// Create a new collection with the specified custom metadata
db.admin().createCollection("collectionName", collectionMetadata);

コレクション・メタデータ・コンポーネント

コレクション・メタデータは複数のコンポーネントから構成されます。

関連項目:

コレクション・メタデータ・コンポーネントの詳細は、OracleRDBMSMetadataBuilderのメソッドのJavadocを参照してください

注意:

コレクション・メタデータ・コンポーネント(スキーマ名、表名、ビュー名、データベースの順序名および列名)に使用する識別子は有効なOracleの引用符付き識別子にする必要があります。脚注6Oracleの引用符付き識別子に許可されている一部の文字および単語はお薦めしません。詳細は、『Oracle Database SQL言語リファレンス』を参照してください)

スキーマ

コレクションがマップされる表またはビューを所有するOracle Databaseスキーマの名前を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

なし

指定できる値

Oracleの有効な引用符付き識別子脚注。この値に二重引用符記号(")または制御文字が含まれている場合、JavaのためのSODAではこれらをアンダースコア文字(_)に置き換えます。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

schemaName()

JSONコレクション・メタデータのドキュメント・パス

schemaName


関連項目:

Oracleの有効な引用符付き識別子の詳細は、『Oracle Database SQL言語リファレンス』を参照してください

表またはビュー

コレクションがマップされる表またはビューの名前を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

なし

指定できる値

Oracleの有効な引用符付き識別子脚注。この値に二重引用符記号(")または制御文字が含まれている場合、JavaのためのSODAではこれらをアンダースコア文字(_)に置き換えます。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

tableName()またはviewName()

JSONコレクション・メタデータのドキュメント・パス

tableNameまたはviewName


関連項目:

Oracleの有効な引用符付き識別子の詳細は、『Oracle Database SQL言語リファレンス』を参照してください

キー列名

ドキュメント・キーを格納する列の名前を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

ID

指定できる値

Oracleの有効な引用符付き識別子脚注(『Oracle Database SQL言語リファレンス』を参照)。この値に二重引用符記号(")または制御文字が含まれている場合、JavaのためのSODAではこれらをアンダースコア文字(_)に置き換えます。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

keyColumnName()

JSONコレクション・メタデータのドキュメント・パス

keyColumn.name


キー列の型

ドキュメント・キーを格納する列のSQLデータ型を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

VARCHAR2

指定できる値

VARCHAR2

NUMBER

RAW(16)

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

keyColumnType()

JSONコレクション・メタデータのドキュメント・パス

keyColumn.sqlType


注意:

クライアント割当てキーが使用され、キー列タイプがVARCHAR2の場合、データベース・キャラクタ・セットにはAL32UTF8が推奨されます。これにより、キーからデータベース・キャラクタ・セットへの変換がロスレスになります。

それ以外の場合、クライアント割当てキーにデータベース・キャラクタ・セットでサポートされない文字が含まれる場合、読取りまたは書込み操作時に、データベース・キャラクタ・セットへのキーの変換は失われます。これにより、挿入操作中に重複キー・エラーが発生することがあります。もっと一般的に言うと、予測できない結果が生じることがあります。たとえば、読取り操作で、予定したキーとは異なるキーに関連付けられている値が返されることがあります。

キー列の最大長

キー列の最大長をバイト単位で指定するコレクション・メタデータ・コンポーネントです。このコンポーネントはVARCHAR2型のキーのみに適用されます。


プロパティ

デフォルト値

255

指定できる値

キーの割当てメソッドがUUIDまたはGUIDの場合、32バイト以上。「キー列の割当てメソッド」を参照してください。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

keyColumnMaxLength()

JSONコレクション・メタデータのドキュメント・パス

keyColumn.maxLength


関連項目:

キー列の型

キー列の割当てメソッド

コレクションに挿入するオブジェクトにキーを割り当てる際に使用されるメソッドを指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

UUID

指定できる値

UUID

GUID

SEQUENCE

CLIENT

これらのメソッドの詳細は、表1-4を参照してください。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

keyColumnAssignmentMethod()

JSONコレクション・メタデータのドキュメント・パス

keyColumn.assignmentMethod



表1-4 キーの割当て方法

メソッド 説明

GUID

キーはSQLファンクションSYS_GUIDによってOracle RDBMSに生成されます。『Oracle Database SQL言語リファレンス』を参照してください。

SEQUENCE

キーはデータベース順序によってOracle Databaseに生成されます。キーの割当てメソッドをSEQUENCEとして指定する場合、その順序名も指定する必要があります。「キー列の順序名」を参照してください。

CLIENT

キーはクライアント・アプリケーションによって割り当てられます。

UUID (デフォルト)

キーは、JavaのためのSODAの基礎となるJava仮想マシン(JVM)のUUID機能に基づいて、JavaのためのSODAによって生成されます。


キー列の順序名

キーの割当てメソッドがSEQUENCEの場合にコレクションに挿入するドキュメントのキーを生成するデータベース順序の名前を指定するコレクション・メタデータ・コンポーネントです。

キーの割当てメソッドをSEQUENCEとして指定する場合、その順序名も指定する必要があります。指定した順序が存在しない場合は、JavaのためのSODAによって作成されます。


プロパティ

デフォルト値

なし

指定できる値

Oracleの有効な引用符付き識別子脚注(『Oracle Database SQL言語リファレンス』を参照)。この値に二重引用符記号(")または制御文字が含まれている場合、JavaのためのSODAではこれらをアンダースコア文字(_)に置き換えます。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

keyColumnSequenceName()

JSONコレクション・メタデータのドキュメント・パス

keyColumn.sequenceName


注意:

JavaのためのSODAを使用してコレクションをドロップする場合、キーの生成に使用する順序はドロップされません。これは、JavaのためのSODAを使用して作成されていないためです。順序をドロップするには、最初にコレクションをドロップしてから、SQLコマンドDROP SEQUENCEを使用します。

関連項目:

  • キー列の割当てメソッド

  • DROP SEQUENCEの詳細は、『Oracle Database SQL言語リファレンス』を参照してください

  • データベース順序の詳細は、『Oracle Database概要』を参照してください

コンテンツ列名

データベース・コンテンツを格納する列の名前を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

JSON_DOCUMENT

指定できる値

Oracleの有効な引用符付き識別子脚注(『Oracle Database SQL言語リファレンス』を参照)。この値に二重引用符記号(")または制御文字が含まれている場合、JavaのためのSODAではこれらをアンダースコア文字(_)に置き換えます。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

contentColumnName()

JSONコレクション・メタデータのドキュメント・パス

contentColumn.name


コンテンツ列の型

ドキュメント・コンテンツを格納する列のSQLデータ型を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

BLOB

指定できる値

VARCHAR2

BLOB

CLOB

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

contentColumnType()

JSONコレクション・メタデータのドキュメント・パス

contentColumn.sqlType


コンテンツ列の最大長

コンテンツ列の最大長をバイト単位で指定するコレクション・メタデータ・コンポーネントです。このコンポーネントはVARCHAR2型のコンテンツのみに適用されます。


プロパティ

デフォルト値

4000

指定できる値

拡張データ型が有効になっている場合、32767。それ以外の場合で列型がVARCHAR2の場合、4000。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

contentColumnMaxLength()

JSONコレクション・メタデータのドキュメント・パス

contentColumn.maxLength


関連項目:

  • コンテンツ列の型

  • 拡張データ型の詳細は、『Oracle Database SQL言語リファレンス』を参照してください

コンテンツ列のJSON検証

JSONコンテンツが従う必要がある構文(厳密構文または緩慢構文)を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

STANDARD

指定できる値

STANDARD

STRICT

LAX (SQL条件is jsonのデフォルト)

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

contentColumnValidation()

JSONコレクション・メタデータのドキュメント・パス

contentColumn.validation


  • STANDARDは、JSON RFC 4627標準に従って検証します。(Oracle SQL条件is jsonに定義された厳密な構文に対応します。)

  • STRICTSTANDARDと同じですが、ドキュメントに重複したJSONフィールド名が含まれていないことも確認する点のみ異なります。(SQLキーワードWITH UNIQUE KEYSも使用する場合、Oracle SQL条件is jsonに定義された厳密な構文に対応します。)

  • LAXは、より緩慢に検証します。(Oracle SQL条件is jsonに定義された緩慢な構文に対応します。)LAXで許可される緩和の一部として、次のものがあります。

    • JSONフィールド名を二重引用符(")で囲む必要はありません。

    • truefalseおよびnullの、大文字、小文字および混在バージョンが許可されます。

    • 数字はその他の方法で表すことができます。

関連項目:

  • JSON構文の厳密な構文および緩慢な構文の詳細は、『Oracle Database JSON開発者ガイド』を参照してください

  • JSON RFC 4627標準については、http://tools.ietf.org/html/rfc4627を参照

コンテンツ列のSecureFiles LOB圧縮

SecureFiles LOB圧縮設定を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

NONE

指定できる値

NONE

HIGH

MEDIUM

LOW

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

contentColumnCompress()

JSONコレクション・メタデータのドキュメント・パス

contentColumn.compress


関連項目:

SecureFiles LOB記憶域の詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照

コンテンツ列のSecureFiles LOBのキャッシュ

SecureFiles LOBのキャッシュ設定を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

TRUE

指定できる値

TRUE

FALSE

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

contentColumnCache()

JSONコレクション・メタデータのドキュメント・パス

contentColumn.cache


関連項目:

SecureFiles LOB記憶域の詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照

コンテンツ列のSecureFiles LOBの暗号化

SecureFiles LOBの暗号化設定を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

NONE

指定できる値

NONE

3DES168

AES128

AES192

AES256

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

contentColumnEncrypt()

JSONコレクション・メタデータのドキュメント・パス

contentColumn.encrypt


関連項目:

SecureFiles LOB記憶域の詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照

バージョン列名

ドキュメント・バージョンを格納する列の名前を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

VERSION

指定できる値

Oracleの有効な引用符付き識別子脚注(『Oracle Database SQL言語リファレンス』を参照)。この値に二重引用符記号(")または制御文字が含まれている場合、JavaのためのSODAではこれらをアンダースコア文字(_)に置き換えます。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

versionColumnName()

JSONコレクション・メタデータのドキュメント・パス

versionColumn.name


バージョン列の生成メソッド

コレクションに挿入するか、置き換わるときにオブジェクトのバージョン値の計算に使用されるメソッドを指定するコレクション・メタデータ・コンポーネントです。

例1-34では、このメタデータ・コンポーネントを使用します。


プロパティ

デフォルト値

SHA256

指定できる値

UUID

TIMESTAMP

MD5

SHA256

SEQUENTIAL

NONE

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

versionColumnMethod()

JSONコレクション・メタデータのドキュメント・パス

versionColumn.method


表1-5に、バージョン生成メソッドを示します。

表1-5 バージョン生成メソッド

メソッド 説明

UUID

ドキュメントが挿入されたときおよび置換操作ごとに、JavaのためのSODAではオブジェクト・コンテンツを無視して、Universally Unique Identifier (UUID)が生成されます。効率的ですが、元のドキュメントと置換後のドキュメントが同じであってもバージョンが変更されます。

バージョン列型の値は、VARCHAR2(255)です。

TIMESTAMP

JavaのためのSODAではオブジェクト・コンテンツを無視して、タイムスタンプから値を生成し、これをLONGに変換します。このメソッドでは、タイムスタンプを取得するためにデータベース・インスタンスへのラウンド・トリップが必要になる可能性があります。UUIDと同様に、元のドキュメントと置換後のドキュメントが同じであってもバージョンが変更されます。

バージョン列型の値は、NUMBERです。

MD5

JavaのためのSODAでは、MD5アルゴリズムを使用してドキュメント・コンテンツのハッシュ値を計算します。このメソッドはUUIDよりも効率的ではありませんが、ドキュメント・コンテンツが変更された場合にのみバージョンが変更されます。

バージョン列型の値は、VARCHAR2(255)です。

SHA256 (デフォルト)

JavaのためのSODAでは、SHA256アルゴリズムを使用してドキュメント・コンテンツのハッシュ値を計算します。このメソッドはUUIDよりも効率的ではありませんが、ドキュメント・コンテンツが変更された場合にのみバージョンが変更されます。

バージョン列型の値は、VARCHAR2(255)です。

SEQUENTIAL

JavaのためのSODAにより、オブジェクトのコンテンツを無視して、オブジェクトが挿入されたときにバージョン1が割り当てられ、オブジェクトが置換されるたびにバージョン値がインクリメントされます。バージョン値はユーザーにわかりやすい値ですが、元のドキュメントと置換後のドキュメントが同じであってもバージョンが変更されます。

バージョン列型の値は、NUMBERです。

NONE

バージョン列が存在する場合、NONEはバージョンがJavaのためのSODAの外部で生成されたことを意味します(たとえば、データベース・トリガーなど)。

関連項目:

指定できる値の詳細は、表1-5を参照してください

最終変更のタイムスタンプの列名

ドキュメントの最終変更のタイムスタンプを格納する列の名前を指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

LAST_MODIFIED

指定できる値

Oracleの有効な引用符付き識別子脚注(『Oracle Database SQL言語リファレンス』を参照)。この値に二重引用符記号(")または制御文字が含まれている場合、JavaのためのSODAではこれらをアンダースコア文字(_)に置き換えます。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

lastModifiedColumnName()

JSONコレクション・メタデータのドキュメント・パス

lastModifiedColumn.name


最終変更の列索引名

最終変更の列索引の名前を指定するコレクション・メタデータ・コンポーネントです。

注意:

このコンポーネントは、現在内部でのみ使用されています。値を変更しないでください。


プロパティ

デフォルト値

なし

指定できる値

Oracleの有効な引用符付き識別子脚注(『Oracle Database SQL言語リファレンス』を参照)。この値に二重引用符記号(")または制御文字が含まれている場合、JavaのためのSODAではこれらをアンダースコア文字(_)に置き換えます。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

lastModifiedColumnIndex()

JSONコレクション・メタデータのドキュメント・パス

lastModifiedColumn.index


作成時のタイムスタンプの列名

ドキュメントの作成時のタイムスタンプを格納する列の名前を指定するコレクション・メタデータ・コンポーネントです。このタイムスタンプは、insertinsertAndGetsaveまたはsaveAndGet操作時に生成されます。

例1-34では、このメタデータ・コンポーネントを使用します。


プロパティ

デフォルト値

CREATED_ON

指定できる値

Oracleの有効な引用符付き識別子脚注(『Oracle Database SQL言語リファレンス』を参照)。この値に二重引用符記号(")または制御文字が含まれている場合、JavaのためのSODAではこれらをアンダースコア文字(_)に置き換えます。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

creationTimeColumnName()

JSONコレクション・メタデータのドキュメント・パス

creationTimeColumn.name


メディア・タイプ列名

ドキュメントのメディア・タイプを格納する列の名前を指定するコレクション・メタデータ・コンポーネントです。異種コレクションの場合、つまり、コレクションがJSON以外のドキュメントを格納できる場合、メディア・タイプ列が必要です。

例1-34では、このメタデータ・コンポーネントを使用します。

注意:

例による問合せ(QBE)を異種コレクションで使用することはできません(試行すると、エラーが発生します)。


プロパティ

デフォルト値

なし

指定できる値

Oracleの有効な引用符付き識別子脚注(『Oracle Database SQL言語リファレンス』を参照)。この値に二重引用符記号(")または制御文字が含まれている場合、JavaのためのSODAではこれらをアンダースコア文字(_)に置き換えます。

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

mediaTypeColumnName()

JSONコレクション・メタデータのドキュメント・パス

mediaTypeColumn.name


読取り専用

コレクションが読取り専用かどうかを指定するコレクション・メタデータ・コンポーネントです。


プロパティ

デフォルト値

FALSE

指定できる値

TRUE

FALSE

コンポーネントを選択する際のOracleRDBMSMetadataBuilderのメソッド

readOnly()

JSONコレクション・メタデータのドキュメント・パス

readOnly




脚注の説明

脚注1:

QBE演算子への引数が必要なタイプではない場合(たとえば、$gtに文字列または数値以外の引数が渡された場合)、構文エラーが発生します。


脚注2:

ここで、フィールドは演算子ではないJSONフィールドです。また、通常SODAで使用する場合、演算子とフィールドは二重引用符(")で囲む必要があります。


脚注4:

配列に少なくとも1つの要素が含まれていない場合、構文エラーが発生します。


脚注5:

配列に少なくとも1つの要素が含まれていない場合、構文エラーが発生します。


脚注6:

リマインダ: 大文字/小文字を区別して解釈されるため、大文字/小文字は引用符で囲まれたSQL識別子では重要です。