Oracle NoSQL Databaseアプリケーションの索引ビューの作成

法律上の注意点

Copyright © 2011, 2012, 2013, 2014, Oracle and/or its affiliates.All rights reserved.

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合がありますまた、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントが、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供される場合は、次のNoticeが適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs.No other rights are granted to the U.S. Government.

このソフトウェアまたはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアまたはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用する際、このソフトウェアまたはハードウェアを安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle およびその関連企業の登録商標です。その他の名称は、他社の商標の可能性があります。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

このソフトウェアまたはハードウェアおよびドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。

3/27/2014


目次

索引ビュー
従来のキー/データ・ペアの使用
キーのみのレコードの使用
複雑な索引名
索引ビュー・メタデータの管理
索引ビュー・レコードとメタデータの併用
キーのサイズに関する考慮事項
索引ビューに関する一般的な考慮事項
追加の書込みアクティビティ
非アトミック更新
整合性の分離

索引ビュー

索引ビューは、プライマリ・レコードに含まれる情報を反映する補助レコードの作成に使用される設計パターンです。様々な方法で索引ビューを作成できます。このドキュメントではそのうちの2つの方法について説明します。

注意

このドキュメントの対象読者は、Oracle NoSQL DatabaseのKey/Value APIを使用中のユーザーで、『Oracle NoSQL Database Key/Value APIスタート・ガイド』を読んで理解している方を想定しています。そのマニュアルをまだお読みになっていない場合は、このドキュメントを読む前にお読みください。

Table APIのユーザーは、組込みの索引付けメカニズムを使用できるため、このドキュメントの対象ではありません。

『Oracle NoSQL Database Key/Value APIスタート・ガイド』レコードの読取りに関する項で説明されているように、通常、レコードはキーのメジャー・パスおよびマイナー・パスを使用してストアから取得されます。キーを使用して1つのレコードを取得することも、メジャー・パスの一部を使用して複数のレコードを取得した後、結果を繰り返すこともできます。

たとえば、ユーザーに関連するレコードがストアに含まれているとします。キーにはユーザーの組織情報およびその他の識別情報(ユーザーIDなど)が含まれる可能性があります。ただし、各レコード・データにはおそらく、名前、住所、電話番号など、個人に関するその他の詳細が含まれています。アプリケーションではユーザーID(つまり、キー・パスの一部として格納されている情報)を使用して個人を頻繁に問い合せることにおそらくなりますが、個人を名前などで探す場合もあります。

ストア内のすべてのレコードを繰り返すのではなく、特定の個人名で各レコードを順に調べることで、アプリケーションで管理される索引ビューを作成できます。索引ビューは複数の方法で実装できますが、通常はキー/値のペアを使用します。この場合、キーはプライマリ・レコード内のいくつかの情報に関連付けられており、値はその情報が存在するプライマリ・レコードを識別します。

つまり、Peterという名前を含むレコードがある場合、その索引ビューのキーにはPeterが含まれ、値にはそのレコードへのメジャーおよびマイナー・キー・パスが含まれることになります。

従来のキー/データ・ペアの使用

索引ビューを作成するこの方法は、キー/値のストアに慣れている多くの開発者がビューを実装しようと直観的に考える方法です。

索引ビューを作成する別の方法については、「キーのみのレコードの使用」を参照してください。

従来のキー/データ・ペア・レコードを使用して索引ビューを作成する場合、作成するレコードは次のようになります。

  • レコードのキー・パスが、迅速に問い合せたいプライマリ・データ・レコード内のいくつかの情報である。

  • レコードのデータが、キー・パスに含まれる情報を持つレコードへのキー・パスである。

たとえば、次のスキーマに使用されるレコードがあるとします。

{
    "type": "record",
    "name": "PrimaryDBValue",
    "namespace": "oracle.kv.indexView",
    "fields": [
        {"name": "name", "type": "string", "default": ""},
        {"name": "email", "type": "string", "default": ""},
        {"name": "phone", "type": "string", "default": ""},
        {"name": "date", "type": "string", "default": ""}, 
        {"name": "org", "type": "string", "default": ""}, 
        {"name": "cost", "type": "long", "default": 0} 
    ]
}

さらに、これらのレコードが従業員の一意の識別子を使用して格納されるとします。たとえば、これらのレコードは、次のように従業員の一意の識別子で終わるキー・パスを使用します。

/Corporate/people/10012
/Corporate/people/10013
/Corporate/people/10014

この場合、"Support"という組織に属するすべての従業員を検索するために、キーが/Corporate/peopleで始まるすべてのレコードを繰り返し、適切な組織名を順に調べた後、その組織に属する従業員のリストを作成します。ストアに含まれる従業員の数に応じて、この操作には時間がかかる可能性があります。

組織名をキーにした索引ビューを作成することもできます。次に例を示します。

/IndexView/People/Organization/Engineering
/IndexView/People/Organization/Sales
/IndexView/People/Organization/Support

これらのレコードのデータ部分を処理するには、2つの方法があります。まず、レコードごとにその組織に属する従業員レコードに対応するキーのリストを含めるという方法があります。つまり、キーは次のようになります。

/IndexView/People/Organization/Support

'org'が'Support'であるすべての従業員エントリのメジャー・キーのリストを持つデータ項目を返します。Avroスキーマとして、データ項目を次の方法で表します。

{
    "type": "record",
    "name": "SecondaryDBValue",
    "namespace": "oracle.kv.indexView",
    "fields": [
        {"name": "arrays", 
         "type": {"type" : "array", "items" : "string"}, 
         "default" : []}
  ]
} 

この方法は小規模から中規模の索引には機能しますが、最終的に規模に対応できなくなります。プライマリ・キーのリストが大きすぎてコードで簡単に処理できないビューは簡単にできてしまいます。実のところ、使用可能なメモリーに収まらないような大きさにすぐに拡大してしまう可能性があります。Oracle NoSQL Databaseが設計されたデータセットのサイズを考慮すると、これは非常に現実的な考慮事項です。

各レコードが唯一のプライマリ・レコードを参照する索引ビューを作成するという方法もあります。つまり、レコードのデータ部分には、プライマリ・レコードへのキー・パスを表す単純な文字列が含まれています(この情報をキー・パス・コンポーネントの配列として伝達することもできます。)ただし、Oracle NoSQL Databaseでキーを複製することはできないため、この場合、プライマリ・レコードにある情報に基づいてキーをなんらかの形で一意にする必要があります。たとえば、組織名とユーザーのUIDの両方を含むキーを作成できます。

/IndexView/People/Organization/Support/-/10012

これは次のプライマリ・レコードを参照します。

/Corporate/People/10012

キーのみのレコードの使用

キーのみの索引ビュー・レコードは、キー内のレコードの情報をすべて伝達します。レコードのデータ部分は空の値に設定されます。この方式では、各索引ビュー・レコードはセカンダリ・キーとキーが参照するプライマリ・レコード・キーとの1つの組合せを表します。Oracle NoSQL Databaseはレコードの大規模化に適しているため、これにより前の項で説明したスケーラビリティの問題が解消されます。

注意

次の例では、かなり長いキー・パスを使用しています。これはわかりやすさのためです。ただし、通常はキー・パスは短い方が望ましいため、ここに示すパスはレコードのキーの作成方法としてお薦めするものではありません。

基本的に、キーのみの索引ビュー・レコードは、キー・パスのメジャー部分で索引ビューのキーを、キー・パスのマイナー部分でプライマリ・レコードのキーを伝達します。つまり、次のようになります。

/Secondary/Key/Path/-/Primary/Key/Path

ここで、マイナー・パス・コンポーネントはプライマリ・レコードのキー・パスです。たとえば、前の項に示した例に基づくと、次のようになります。

/Secondary/Key/Path/-/Corporate/people/10012

レコードのメジャー・キー・パス部分は詳細情報を伝達する必要があります。

  • 索引キーの接頭辞

    これは、レコードが索引ビュー・レコードであることを示すために使用される接頭辞値です。ストア内で一意であるかぎり、接頭辞はIDXなど、どのようなものでもかまいません。

  • 索引名

    これは、この索引ビューを他のタイプの索引ビューと区別するために使用されます。このレコードで索引付けされる情報を示す単純な名前(EMPLOYEE_NAMEEMPLOYEE_LOCATIONなど)を使用できます。ただし、コードを正しく設定した場合、さらに複雑な情報を伝達することもできます。これは、「複雑な索引名」で詳しく説明します。

  • フィールド値

    メジャー・キー・パスの残りの部分は、関連するプライマリ・レコードから取得された一連の1つ以上のフィールド値です。これは、索引付けする実際の情報です。

    最も単純な例では、キーのこの部分には1つのフィールド値のみが含まれます。たとえば、すべての従業員に組織で索引付けする場合は、組織名になります。次に例を示します。

    /IDX/ORGANIZATION/Engineering/-/Corporate/people/10012

    これは、従業員レコード10012がエンジニアリング組織に属していることを示すビュー・エントリです。

    ただし、キー・パスのこの部分には複数のフィールド値を含めることができます。この場合、複数列のビューになります。この例としては、従業員の共通の名前と姓による索引付けがあります。どちらもプライマリ・レコードでは個別のフィールドになります。

    /IDX/EMP_NAME/Smith/Robert/-/Corporate/people/10012
    /IDX/EMP_NAME/Smith/Patricia/-/Corporate/people/40288
    /IDX/EMP_NAME/Smyth/Don/-/Corporate/people/7893

複雑な索引名

前述のように、特に索引付け要件が単純な場合、索引名は単純なテキスト・ラベルにできます。ただし、索引名でビュー・レコードに関する詳細情報を伝達することもできます。次のものを識別できるように索引名を作成できます。

  • プライマリ・レコードで使用されるAvroスキーマ名。

  • このビューが索引付けしているフィールド名のリスト。特に、索引付けしているフィールドの数が増えたり索引ビューのタイプの数が増えてくると、この情報は、Avroバインディング・コードを一般化するのに役立ちます。

この情報を伝達する索引名を作成するには、索引名に必要なすべての情報を保持するリスト・オブジェクトを作成した後、java.security.MessageDigestを使用して情報の一方向ハッシュを作成するという方法があります。リストのバイト配列への変換は、Key.createKey()メソッドを使用して実行できます。次に例を示します。

    /**
     * Construct and return an index name representing an index type.
     */
    private String getIndexName(String schemaName,
                                List<String> indexFieldNames) {

        MessageDigest md = null;
        try {
            /* 
             * The implementation for digestCache is omitted 
             * for brevity.
             */
            md = digestCache.get();
            List<String> minorPath = new ArrayList<String>();
            minorPath.add(schemaName);
            minorPath.addAll(indexFieldNames);
            byte[] bytes = 
                Key.createKey("", minorPath).toString().getBytes();
            md.update(bytes);
            return new String(md.digest());
        } finally {
            digestCache.free(md);
        }
    } 

これは、索引名で伝達する情報は一方向ハッシュでロックされることを意味します。その情報をハッシュから取得する方法はないため、ある場所に保存する必要があります。索引ビュー・メタデータを記録するには、個別のレコード・セットが必要です。

索引ビュー・メタデータの管理

索引ビュー・メタデータは、各索引タイプについて記録する情報です。通常、これは索引名の作成に使用する情報です(複雑な索引名を使用する場合)。索引の状態をメタデータの一部として記録することもできます。

索引ビュー・メタデータを一連のキーのみのレコードとして収集できます。この場合、キーは次のように作成されます。

/PREFIX/INDEX_NAME/-/SCHEMA_NAME/FNAME1/FNAME2/.../STATE

それぞれの意味は次のとおりです。

  • PREFIXは、このレコードが索引ビュー・メタデータ・レコードであることを示すために使用する一意の識別子です。たとえば、METAなどです。

  • INDEX_NAMEは、メタデータを収集する索引のタイプに使用する名前です。単純な名前(ORGANIZATIONEMP_NAMEなど)を使用している場合は、その名前を使用します。前の項で説明したような、ハッシュ化された複雑な名前を使用している場合は、その名前をここで使用します。

  • SCHEMA_NAMEは、プライマリ・レコードで使用されるAvroスキーマの名前です。これは、複雑な索引名の作成に使用したのと同じスキーマ名である必要があります。

  • FNAME1FNAME2などは、このビュー・タイプが使用しているプライマリ・レコードのフィールド名です。これらの名前も、複雑な索引名の作成に使用したフィールド名と同じである必要があります。また、索引ビュー・レコード・キーの作成に使用したフィールド値と同じ順序で表示される必要があります。

  • STATEは、このメタデータ・レコードで表される索引タイプの現在の状態です。ビューSTATEの例は、次のとおりです。

    • BUILDINGは、索引ビューが現在作成中であることを示します。

    • DELETINGは、索引ビューが現在削除中であることを示します。

    • READYは、索引ビューを使用する準備ができたことを示します。

    これらは提案にすぎません。STATEは、コードに役立つ情報を示すことができます。ただし、ここに示した例では、コードがビューを使用するのは状態がREADYの場合のみです。

索引ビュー・レコードとメタデータの併用

すべてをまとめて複雑な索引名を使用する索引ビューを作成するには、次の手順を実行します。

  1. 作業しているスキーマ名とフィールド名を使用して索引名を作成します。

  2. 前の項で説明したようにメタデータ・レコードを作成し、状態をBUILDINGに設定します。

  3. 使用するストアについてこの手順を繰り返し、索引付けするプライマリ・レコードごとにビュー・レコードを作成します。ビュー・レコードのメジャー・キー・パスの一部として、手順1で作成した索引名を使用します。詳細は、「キーのみのレコードの使用」および「複雑な索引名」を参照してください。

  4. ビューの作成が完了したら、メタデータ・レコードのステータスをREADYに変更します(そのためには、古いレコードを削除して新しいレコードを作成します)。

索引ビューを使用する(読み取る)には、次の手順を実行します。

  1. 対応するメタデータ・レコードを確認し、索引ビューがREADY状態であることを確認します。そうでない場合は、読取りを中止するか、状態がREADYに変わるまで一時停止できます。

  2. 検索する索引ビュー・レコードについてこの手順を繰り返します。

  3. そのようなレコードごとに、そのレコードを使用して対応するプライマリ・レコードを取得します。

  4. プライマリ・レコードごとに、対応するメタデータ・レコードに含まれるスキーマ名とフィールド名をAvroバインディングとともに使用して、プライマリ・レコードのデータをシリアライズ/デシリアライズします。

既存のレコードを更新するには、次の手順を実行します。

  1. プライマリ・レコードを取得します。

  2. 索引ビュー・レコードを取得します。

  3. 必要に応じてプライマリ・レコードを変更します。

  4. 変更がプライマリ・レコードに反映されるように索引ビュー・レコードを変更します。

  5. 索引ビューのステータスを確認して、READY状態であることを確認します。そうである場合は、索引ビュー・レコードをストアに書き戻します。

    索引ビューのステータスがREADYではない場合は、索引ビュー・レコードを書き込む前にステータスがREADYに変わるまで待機するか、操作を中断します。

  6. 変更したプライマリ・レコードをストアに書き戻します。

これらの操作をすべて実行する例は、Oracle NoSQL Databaseディストリビューションに含まれています。詳細は、「例」を参照してください。

キーのサイズに関する考慮事項

キーが長くなるほど、ノードで使用するメモリーが増えます。したがって、キャッシュ内に十分なレコードを保持できないため、キーはシステムの読取り/書込みスループット全体に損害を与えるほど大きくなる可能性があります。

ここで説明するキーのみの設計パターンでは、キーが非常に長くなる可能性が高いです。キー・サイズが非常に大きいためにパフォーマンスの問題が発生するかどうかは、キーが実際に存在する期間、管理する必要があるキーの数、およびノードで使用可能なメモリーの量に依存します。

キーが非常に大きいためにI/Oスループットの問題が発生する場合は、他の設計方法を実装する必要があります。

索引ビューに関する一般的な考慮事項

索引ビューを作成すると、(データ・セットのサイズおよびそれに対する質問の種類に応じて)ストアの読取りパフォーマンスが大幅に向上しますが、注意が必要ないくつかの制限事項があります。

追加の書込みアクティビティ

索引ビューをやむを得ず保持する場合、プライマリ・レコードの保持に必要なアクティビティに加えて、追加の読取りおよび書込みアクティビティが必要です。この追加のアクティビティが書込みスループットに目に見えて影響するかどうかは、索引付けするデータセットのサイズ、およびビューのサイズによって異なります。

小さいデータセットと小さいビューの場合、この追加のアクティビティは目立ちません。ただし、索引付けされるデータのサイズが大きくなり、ビュー自体が大きくなるにつれて、スループット、特に書込みスループットの低下が見られるようになる可能性があります。このような場合は、ストア・サイズを計画するときに、索引ビューを保持するためのオーバーヘッドを考慮するようにしてください。

非アトミック更新

索引ビューはアプリケーションで管理されるため、Oracle NoSQL Databaseは、プライマリ・レコードで実行される操作が、対応するビュー・レコードで実行される操作とアトミックであることは保証できません。これは、プライマリ・レコードの変更は可能ですが、索引ビューでの対応する操作が失敗すると、プライマリ・データと同期されなくなることを意味します。その逆も発生する可能性があります。索引ビューの更新操作は成功したものの、プライマリ・レコードに対する更新は失敗するという場合です。

一部のワークロードでは、プライマリ・レコードおよびその索引ビューに対する非アトミック更新が望ましいことに注意してください。これは、考えうる最大の読取りおよび書込みスループットを必要とするワークロードの場合にときおり言えることです。このようなタイプのアプリケーションの場合、索引ビューとプライマリ・データの間の整合性は、全体のパフォーマンスに比べると重要ではありません。

いずれにしても、コードが問題を検出した場合に補正トランザクションを実行できるように、索引がプライマリ・データに対して非同期になっていないかどうかを確認してみる必要があります。更新操作のある局面が失敗した場合、索引ビューに安全でない状態であるとしてフラグを設定する必要もあります。索引ビューを保持しているプライマリ・レコードを更新する最も安全な方法(必ずしも最も速い方法とはかぎりません)は、次のとおりです。

  1. ビューがREADY状態かどうかを確認します。そうである場合は更新操作に進みます。そうではない場合は、一時停止して状態が変化するまで待機するか、更新を完全に中止します。

  2. 必要に応じてプライマリ・レコードを更新しますが、まだ結果をストアに書き戻さないでください

  3. プライマリ・レコードに対して加えた変更を反映するように索引ビューを更新します。

  4. プライマリ・レコードをストアに書き込みます。書込みに失敗した場合は、補正トランザクションを実行して問題を修正します。更新されたレコードで書込み操作を再試行するか、または現在ストアに存在するレコードがなんらかの形で破損または変更されていないことを確認します。

  5. プライマリ・レコードの更新が成功した場合は、索引ビューの変更をストアに書き込みます。これが成功すると、更新は完了です。

  6. 索引ビュー・レコードの更新に失敗した場合は、ただちに索引ビューを非READY状態であるとしてマークします。これを実行する方法は、索引ビューの状態フラグをどのように保存しているかによって異なりますが、メタデータ・レコードを使用している場合は、索引ビューを修正する手順を実行する前にフラグを更新する必要があります。

プライマリ・レコードの作成および削除にも同様のアルゴリズムが必要です。

もちろんこれは、索引ビューの読取りを実行する前に、ビューの状態を確認してから続行する必要があるということです。ビューの状態がREADYではない場合は、状態がREADYになるまで一時停止するか、読取りを完全に中止する必要があります。この確認以外に、索引ビューが、プライマリ・レコードと整合性がある状態であることも確認する必要があります。これについては、次の項で説明します。

整合性の分離

前述のように、索引ビューは、更新操作の包括的な障害によりプライマリ・データと同期できない可能性があります。コードは、このような問題が発生するタイミングを認識できるだけの堅牢性を備えていなければならず、かつ適切な措置を講じる必要があります(必要に応じて索引ビューの再構築まで含みます)。関連する一時的な問題として、特定のノードでは、ビューを変更してもレプリケーションの遅延によりプライマリ・レコードの変更に追い付かない可能性があります。対応するプライマリ・データの変更がまだ始まっていなくても、ローカル・ノードのビューの更新は終わっているという可能性もありますので注意してください。

また、一部のワークロードでは、ビューがプライマリ・データと同期しているかどうかはそれほど重要ではない場合があります。ただし、ワークロードでビューにプライマリ・データが正確に反映されていることが必要な場合は、Oracle NoSQL Databaseの組込みの整合性保証機能を利用する必要があります。

1つの方法としては、ビューを使用して実行する読取りには絶対整合性保証を使用することです。ただし、絶対整合性では読取り操作をマスター・ノードで実行する必要があるため、読取りおよび書込みのパフォーマンスが低下する可能性があります(詳細は、『Oracle NoSQL Database Key/Value APIスタート・ガイド』事前定義済の整合性の使用に関する項を参照してください)。このため、ビューがプライマリ・データに対して完全に最新の状態であることが重要な場合のみ、絶対整合性を使用してください。

この問題を解決する方法としては、索引ビューを使用するときにバージョンベースの整合性保証を使用する方が適しています。読取りを実行してプライマリ・データとビューが同期していることを確認する際に、プライマリ・データとビューの両方でバージョン情報を確認する必要があります。あるプロセスがストアの書込みを実行し、別のプロセスがストアの読取りを実行する場合、アプリケーションの異なるプロセス間でバージョン情報を転送する方法を作成することも必要です。バージョンベースの整合性の使用の詳細は、『Oracle NoSQL Database Key/Value APIスタート・ガイド』バージョンベースの整合性の使用に関する項を参照してください。

索引ビューの作成および管理の例は、Oracle NoSQL Databaseディストリビューションに含まれています。次の場所にあります。

<KVROOT>/examples/secondaryindex

この例では、索引ビューの作成と削除、索引ビュー・レコードで参照されるプライマリ・データの取得、新しいプライマリ・レコードの挿入、削除および更新を実行できるコマンドライン・インタフェースが公開されています。このアプリケーションは、顧客請求レコードに対してビューを作成可能な非常に単純なアプリケーションです。

この例では、複雑な索引名と関連するメタデータ・レコードを持つ、キーのみの索引ビュー・レコードを使用します。ビューおよび関連するメタデータの管理を行うコードは、次のクラスに含まれています。

<KVROOT>/examples/secondaryindex/IndexViewService.java

この例は、索引ビューの設計パターンの1つであることに注意してください。操作は自分のコードが動作する方法と一致しない可能性もありますが、適切な設計ガイドとして役立ちます。独自の設計のニーズおよび目標にあわせて、自由にサンプル・コードを改変、展開または簡略化してください。