コンテンツ コネクタを作成する

コンテンツ コネクタは、企業のリポジトリ内のデータを走査して所定のデータソースを完成する目的で使われるソフトウェア プログラムです。Google は、コンテンツ コネクタを開発するためのオプションを提供しています。

  • Content Connector SDK。Java でプログラミングしているデベロッパー向けのオプションです。Content Connector SDK は、コネクタをすばやく作成するための REST API を簡単に使えるようにしたラッパーです。この SDK でコンテンツ コネクタを作成する場合は、Content Connector SDK を使用してコンテンツ コネクタを作成するを参照してください。

  • 低レベル REST API、その他の各種の API ライブラリ。Java を使用していないデベロッパーや、コードベースが REST API やライブラリに問題なく対応できるデベロッパーの方は、これらのオプションをご利用ください。この REST API を使用してコンテンツ コネクタを作成する場合は、REST API を使用してコンテンツ コネクタを作成するを参照してください。

コンテンツ コネクタで行われる標準的なタスクは次のとおりです。

  1. 構成パラメータを読み取り、処理する。
  2. インデックス登録可能な離散的なデータチャンク(これを「アイテム」と呼びます)をサードパーティのコンテンツ リポジトリから pull する。
  3. ACL、メタデータ、コンテンツ データを結合して、インデックス登録可能なアイテムを作成する。
  4. アイテムを Cloud Search データソースにインデックス登録する。
  5. (省略可)サードパーティのコンテンツ リポジトリからの変更通知を待ち受ける。変更通知をインデックス登録リクエストに変換し、これで Cloud Search データソースとサードパーティのリポジトリとの同期を維持します。なお、コンテンツ コネクタによるこのタスクは、リポジトリが変更検出機能に対応している場合にのみ行われます。

Content Connector SDK を使用してコンテンツ コネクタを作成する

以降のセクションでは、Content Connector SDK を使用してコンテンツ コネクタを作成する方法について説明します。

依存関係を設定する

SDK を使用するには、ビルドファイルに特定の依存関係を含める必要があります。使用するビルド環境の依存関係を表示するには、以下のタブをクリックします。

Maven

<dependency>
    <groupId>com.google.enterprise.cloudsearch</groupId>
    <artifactId>google-cloudsearch-indexing-connector-sdk</artifactId>
    <version>v1-0.0.3</version>
    </dependency>
    

Gradle

compile group: 'com.google.enterprise.cloudsearch',
            name: 'google-cloudsearch-indexing-connector-sdk',
            version: 'v1-0.0.3'
    

コネクタ構成を作成する

コネクタごとに構成ファイルを作成し、コネクタが使用するパラメータ(リポジトリの ID など)を含めます。パラメータは、次のように Key-Value ペアで定義します。

api.sourceId=1234567890abcdef

Google Cloud Search SDK には、すべてのコネクタで使用される Google 提供の構成パラメータが複数含まれています。以下の Google 提供パラメータを構成ファイル内で宣言してください。

  • コンテンツ コネクタの場合は、api.sourceIdapi.serviceAccountPrivateKeyFile を宣言する必要があります。これらのパラメータは、リポジトリと秘密鍵の場所を指定するもので、リポジトリにアクセスするのに必要です。
  • ID コネクタの場合は、api.identitySourceId を宣言する必要があります。このパラメータは、外部の ID ソースの場所を指定します。ユーザー間の同期を行う場合は、api.customerId も宣言してください。このパラメータは、会社の G Suite アカウントを識別する ID として使用されます。

上記以外の Google 提供パラメータについては、デフォルト値を特にオーバーライドしたくなければ構成ファイルで宣言する必要はありません。Google 提供の構成パラメータに関するその他の情報(ID や鍵を生成する方法など)については、Google 提供の構成パラメータをご覧ください。

独自のリポジトリ パラメータを定義して、構成ファイル内で使用することもできます。

注: コネクタのプロパティ ファイルに関する厳密な命名要件はありませんが、拡張子 .properties または .config を付けてファイルを保存することをおすすめします。

構成ファイルをコネクタに渡す

構成ファイルがコネクタに渡されるようにシステム プロパティ config を設定します。このプロパティは、コネクタを起動するとき -D 引数で設定できます。たとえば、次のコマンドは、MyConfig.properties 構成ファイルを使用してコネクタを起動します。

java -classpath myconnector.jar;... -Dconfig=MyConfig.properties MyConnector
    

この引数がないと、SDK はデフォルトの構成ファイル connector-config.properties にアクセスしようとします。

使用する走査戦略を決める

コンテンツ コネクタの主な機能は、リポジトリを走査してそのデータをインデックス登録することです。お使いのリポジトリ内のデータの規模と配置に基づいて走査戦略を実装してください。独自の戦略を設計することも、SDK に実装されている以下の戦略から選択することもできます。

フル走査戦略

リポジトリ全体をスキャンして、すべてのアイテムを無分別にインデックス登録する戦略です。フル走査は、リポジトリの規模が小さく、インデックス登録するたびに全体を走査してもオーバーヘッドを許容できる場合によく使われる戦略です。

フル走査戦略は、概ね静的で階層構造を持たないデータを含む小規模なリポジトリに向いています。変更検出が困難なリポジトリや変更検出機能をサポートしていないリポジトリで使用することもあります。

リスト走査戦略

すべての子ノードを含むリポジトリ全体をスキャンして各アイテムのステータスを確認した後、2 回目のパスで前回のインデックス登録以降に作成または更新されたアイテムのみをインデックス登録する戦略です。リスト走査戦略は、インデックスを更新するたびに全体を走査しなくてもよい場合に、既存のインデックスを増分更新するためによく使われる戦略です。

リスト走査戦略は、変更検出が困難なリポジトリや変更検出機能をサポートしていないリポジトリで、データが階層化されておらず、扱うデータセットが非常に大規模であるようなケースに向いています。

グラフ走査戦略

親ノード全体をスキャンして各アイテムのステータスを確認した後、2 回目のパスで前回のインデックス登録以降に作成または更新されたルートノード内のアイテムのみをインデックス登録し、その後、該当するすべての子 ID を引き渡し、作成または更新された子ノード内のアイテムをインデックス登録する戦略です。コネクタは、該当するアイテムがすべて処理されるまで、すべての子ノードを再帰的にスキャンします。この種の走査は、通常、ID をすべてリストすることが現実的でない階層的なリポジトリに対して使われます。

この戦略は、一連のディレクトリやウェブページなど、クロールする必要がある階層データがある場合に適しています。

上記の各走査戦略の実装には SDK のテンプレート コネクタクラスが使われています。独自の走査戦略を実装することも可能ですが、これらのテンプレートを利用すればコネクタの開発期間を大幅に短縮できます。テンプレートを利用してコネクタを作成する場合は、使用する走査戦略に対応するセクションに進んでください。

テンプレート クラスを使用してフル走査コネクタを作成する

このドキュメント セクションのコード スニペットは、FullTraversalSample サンプルからの抜粋です。

コネクタのエントリ ポイントを実装する

コネクタのエントリ ポイントは main() メソッドです。このメソッドの主なタスクは、Application クラスのインスタンスを作成し、start() メソッドを起動してコネクタを実行することです。

application.start() を呼び出す前に、IndexingApplication.Builder クラスを使用して FullTraversalConnector テンプレートをインスタンス化します。FullTraversalConnector は、実装するメソッドを含む Repository オブジェクトを受け入れます。次のコード スニペットは、main() メソッドの実装方法を示しています。

FullTraversalSample.java
/**
     * This sample connector uses the Cloud Search SDK template class for a full
     * traversal connector.
     *
     * @param args program command line arguments
     * @throws InterruptedException thrown if an abort is issued during initialization
     */
    public static void main(String[] args) throws InterruptedException {
      Repository repository = new SampleRepository();
      IndexingConnector connector = new FullTraversalConnector(repository);
      IndexingApplication application = new IndexingApplication.Builder(connector, args).build();
      application.start();
    }

バックグラウンドでは、コネクタの main() メソッドが Application.build を呼び出した後に、SDK が initConfig() メソッドを呼び出します。initConfig() メソッドは、次のタスクを実行します。

  1. Configuation.isInitialized() メソッドを呼び出して、Configuration がまだ初期化されていないことを確認します。
  2. Google 提供の Key-Value ペアで Configuration オブジェクトを初期化します。Configuration オブジェクト内の ConfigValue オブジェクトに各 Key-Value ペアが格納されます。

Repository インターフェースを実装する

Repository オブジェクトの唯一の目的は、リポジトリ アイテムを走査してインデックス登録することです。テンプレートを利用すると、Repository インターフェースの一部のメソッドをオーバーライドするだけでコンテンツ コネクタを作成できます。オーバーライドするメソッドは、使用するテンプレートと走査戦略によって異なります。FullTraversalConnector の場合は、次のメソッドをオーバーライドします。

  • init() メソッド。データ リポジトリをセットアップして初期設定するには、init() メソッドをオーバーライドします。

  • getAllDocs() メソッド。データ リポジトリ内のすべてのアイテムを走査してインデックス登録するには、getAllDocs() メソッドをオーバーライドします。このメソッドは、(構成で定義した)スケジュールに従い走査が行われるたびに 1 回呼び出されます。

  • (省略可)getChanges() メソッド。リポジトリが変更検出機能をサポートしている場合、getChanges() メソッドをオーバーライドします。このメソッドは、(構成で定義した)スケジュールに従い増分走査が行われるたびに 1 回呼び出され、変更されたアイテムを取得してインデックス登録します。

  • (省略可)close() メソッド。リポジトリをクリーンアップする必要がある場合は、close() メソッドをオーバーライドします。このメソッドは、コネクタのシャットダウン時に 1 回呼び出されます。

Repository オブジェクトの各メソッドにより、ApiOperation オブジェクトの一種が返されます。ApiOperation オブジェクトにより、単一または複数の形式でアクションが実行され、IndexingService.indexItem() 呼び出しでリポジトリの実際のインデックス登録を実行します。

カスタム構成パラメータを取得する

コネクタを構成する過程で、Configuration オブジェクトからいずれかのカスタム パラメータを取得する必要があります。このタスクは通常、Repository クラスの init() メソッドで実行します。

Configuration クラスには、構成から異なるデータ型を取得するメソッドがいくつかあります。各メソッドにより ConfigValue オブジェクトが返されます。その後、ConfigValue オブジェクトの get() メソッドを使用して実際の値を取得します。次のコード スニペット(FullTraversalSample からの抜粋)は、Configuration オブジェクトから単一のカスタム整数値を取得する方法を示しています。

FullTraversalSample.java
@Override
    public void init(RepositoryContext context) {
      log.info("Initializing repository");
      numberOfDocuments = Configuration.getInteger("sample.documentCount", 10).get();
    }

複数の値を含むパラメータを取得して解析するには、Configuration クラスのいずれかの型パーサーを使用してデータを個別のチャンクに解析します。次のコード スニペット(チュートリアル コネクタからの抜粋)は、getMultiValue メソッドを使用して GitHub リポジトリの名前のリストを取得しています。

GithubRepository.java
ConfigValue<List<String>> repos = Configuration.getMultiValue(
        "github.repos",
        Collections.emptyList(),
        Configuration.STRING_PARSER);

フル走査を実行する

getAllDocs() をオーバーライドしてフル走査を実行し、リポジトリをインデックス登録します。getAllDocs() メソッドはチェックポイントを受け取って処理します。チェックポイントは、プロセスが中断された場合に特定のアイテムからインデックス登録を再開する目的で使用します。リポジトリ内のアイテムごとに、getAllDocs() メソッド内で以下の手順を実行します。

  1. アクセス許可を設定する。
  2. インデックス登録するアイテムのメタデータを設定する。
  3. メタデータとアイテムを結合して、インデックス登録可能な 1 つの RepositoryDoc を作成する。
  4. インデックス登録可能な各アイテムを getAllDocs() メソッドから返されるイテレータにパッケージ化する。なお、getAllDocs() が実際に返すのは CheckpointCloseableIterable であり、これは ApiOperation オブジェクトのイテレーションです。この各オブジェクトは RepositoryDoc で実行した API リクエスト(インデックス登録など)を表します。

1 回の呼び出しで処理するにはアイテムが多すぎる場合は、チェックポイントを含め、hasMore(true) を設定してください。これにより、インデックス登録可能なアイテムがまだあることを示します。

アイテムへのアクセス許可を設定する

リポジトリは、アイテムにアクセスできるユーザーまたはグループを識別するためにアクセス制御リスト(ACL)を使用しています。ACL とは、アイテムにアクセスできるグループまたはユーザーの ID のリストです。

この ACL をデータソースに複製して、検索を実行したユーザーに、アクセス権を持つアイテムのみが表示されるようにする必要があります。同様に、アイテムをインデックス登録するときに、アイテムの ACL を含めてください。これは、Google Cloud Search がアイテムに適切なアクセスレベルを提供するために必要な情報です。

Content Connector SDK は、リポジトリの ACL をモデル化するために必要な一連の ACL クラスやメソッドを潤沢に提供しているため、ほとんどのリポジトリに対応できます。アイテムをインデックス登録するときは、リポジトリ内の各アイテムの ACL を分析して、Google Cloud Search の対応する ACL を作成する必要があります。リポジトリの ACL で ACL の継承といったコンセプトが用いられている場合、その ACL をモデル化するのは厄介な作業になるかもしれません。Google Cloud Search の ACL の詳細は、Google Cloud Search の ACL を参照してください。

注: Cloud Search の Indexing API がサポートしているのは単一ドメインの ACL であって、クロスドメインの ACL ではありません。原則として、ACL を使用する各アイテムへのアクセスを設定するには、Acl.Builder クラスを使用します。次のコード スニペット(フル走査のサンプルからの抜粋)は、検索を行う際に、すべてのユーザー、つまり「プリンシパル」(getCustomerPrincipal())がすべてのアイテムの「リーダー」(.setReaders())になることを許可しています。

FullTraversalSample.java
// Make the document publicly readable within the domain
    Acl acl = new Acl.Builder()
        .setReaders(Collections.singletonList(Acl.getCustomerPrincipal()))
        .build();

ACL について理解していないとデータソースの ACL を適切にモデル化することはできません。たとえば、あるファイル システムのファイルをインデックス登録するとき、そのファイル システムである種の継承モデルが用いられているために、子フォルダが親フォルダからアクセス権を継承する場合があります。ACL の継承をモデル化するためには、Google Cloud Search の ACL で解説している追加情報が必要です。

アイテムのメタデータを設定する

メタデータは Item オブジェクトに格納されます。Item の作成に必要な最低限の情報は、文字列型の一意の ID、アイテムタイプ、ACL、URL、アイテムのバージョンです。次のコード スニペットは、IndexingItemBuilder ヘルパークラスを使用して Item を作成する方法を示しています。

FullTraversalSample.java
// Url is required. Use google.com as a placeholder for this sample.
    String viewUrl = "https://www.google.com";

    // Version is required, set to current timestamp.
    byte[] version = Longs.toByteArray(System.currentTimeMillis());

    // Using the SDK item builder class to create the document with appropriate attributes
    // (this can be expanded to include metadata fields etc.)
    Item item = IndexingItemBuilder.fromConfiguration(Integer.toString(id))
        .setItemType(IndexingItemBuilder.ItemType.CONTENT_ITEM)
        .setAcl(acl)
        .setSourceRepositoryUrl(IndexingItemBuilder.FieldOrValue.withValue(viewUrl))
        .setVersion(version)
        .build();

インデックス登録可能なアイテムを作成する

アイテムのメタデータを設定すると、RepositoryDoc.Builder クラスを使用する実際のインデックス登録可能なアイテムを作成できるようになります。次の例は、単一のインデックス登録可能なアイテムを作成する方法を示しています。

FullTraversalSample.java
// For this sample, content is just plain text
    String content = String.format("Hello world from sample doc %d", id);
    ByteArrayContent byteContent = ByteArrayContent.fromString("text/plain", content);

    // Create the fully formed document
    RepositoryDoc doc = new RepositoryDoc.Builder()
        .setItem(item)
        .setContent(byteContent, IndexingService.ContentFormat.TEXT)
        .build();

RepositoryDoc は、実際の IndexingService.indexItem() リクエストを実行する ApiOperation の一種です。

RepositoryDoc.Builder クラスの setRequestMode() メソッドを使用して、インデックス登録リクエストのモードを ASYNCHRONOUS または SYNCHRONOUS に指定することもできます。

ASYNCHRONOUS
非同期モードに設定すると、インデックス登録してから結果を得るまでのレイテンシが長くなり、インデックス登録リクエストに対する処理割り当て量の供給が増えます。非同期モードは、リポジトリ全体を最初にインデックス登録(バックフィル)するケースで使うことをおすすめします。
SYNCHRONOUS
同期モードに設定すると、インデックス登録してから結果を得るまでのレイテンシが短くなり、処理割り当て量の供給が制限されます。同期モードは、リポジトリの更新や変更をインデックス登録するケースで使うことをおすすめします。省略時のリクエスト モードはデフォルトで SYNCHRONOUS になります。

イテレータ内のインデックス登録可能な各アイテムをパッケージ化する

getAllDocs() メソッドは、Iterator、具体的には RepositoryDoc オブジェクトの CheckpointCloseableIterable を返します。CheckpointClosableIterableImpl.Builder クラスを使用すると、イテレータを構築して返すことができます。次のコード スニペットは、イテレータを構築して返す方法を示しています。

FullTraversalSample.java
CheckpointCloseableIterable<ApiOperation> iterator =
      new CheckpointCloseableIterableImpl.Builder<>(allDocs).build();

SDK は、イテレータの範囲に含まれる各インデックス登録呼び出しを実行します。

次のステップ

必要に応じて次の手順を行います。

テンプレート クラスを使用してリスト走査コネクタを作成する

Cloud Search インデックス登録キューの目的は、リポジトリ内の各アイテムの ID(および必要に応じてハッシュ値)を保持することです。リスト走査コネクタは、Google Cloud Search インデックス登録キューにアイテム ID を push し、インデックス登録のためにそこから 1 つずつ取得します。Google Cloud Search はキューを維持管理し、キューの内容を比較することでアイテムのステータス(アイテムがリポジトリから削除済みかどうかなど)を確認します。Cloud Search インデックス登録キューの詳細については、Google Cloud Search インデックス登録キューをご覧ください。

このドキュメント セクションのコード スニペットは、ListTraversalSample サンプルからの抜粋です。

コネクタのエントリ ポイントを実装する

コネクタのエントリ ポイントは main() メソッドです。このメソッドの主なタスクは、Application クラスのインスタンスを作成し、start() メソッドを起動してコネクタを実行することです。

application.start() を呼び出す前に、IndexingApplication.Builder クラスを使用して ListingConnector テンプレートをインスタンス化します。ListingConnector は、実装するメソッドを含む Repository オブジェクトを受け取って処理します。次のコード スニペットは、ListingConnector とそれに関連する Repository をインスタンス化する方法を示しています。

ListTraversalSample.java
/**
     * This sample connector uses the Cloud Search SDK template class for a
     * list traversal connector.
     *
     * @param args program command line arguments
     * @throws InterruptedException thrown if an abort is issued during initialization
     */
    public static void main(String[] args) throws InterruptedException {
      Repository repository = new SampleRepository();
      IndexingConnector connector = new ListingConnector(repository);
      IndexingApplication application = new IndexingApplication.Builder(connector, args).build();
      application.start();
    }

バックグラウンドでは、コネクタの main() メソッドが Application.build を呼び出した後に、SDK が initConfig() メソッドを呼び出します。initConfig() メソッドは、次のタスクを実行します。

  1. Configuation.isInitialized() メソッドを呼び出して、Configuration がまだ初期化されていないことを確認します。
  2. Google 提供の Key-Value ペアで Configuration オブジェクトを初期化します。Configuration オブジェクト内の ConfigValue オブジェクトに各 Key-Value ペアが格納されます。

Repository インターフェースを実装する

Repository オブジェクトの唯一の目的は、リポジトリ アイテムを走査してインデックス登録することです。テンプレートを利用すると、Repository インターフェースの一部のメソッドをオーバーライドするだけでコンテンツ コネクタを作成できます。オーバーライドするメソッドは、使用するテンプレートと走査戦略によって異なります。ListingConnector の場合は、次のメソッドをオーバーライドします。

  • init() メソッド。データ リポジトリをセットアップして初期設定するには、init() メソッドをオーバーライドします。

  • getIds() メソッド。リポジトリ内のすべてのレコードの ID とハッシュ値を取得するには、getIds() メソッドをオーバーライドします。

  • getDoc() メソッド。インデックス内のアイテムを追加、更新、変更、削除するには、getDoc() メソッドをオーバーライドします。

  • (省略可)getChanges() メソッド。リポジトリが変更検出機能をサポートしている場合、getChanges() メソッドをオーバーライドします。このメソッドは、(構成で定義した)スケジュールに従い増分走査が行われるたびに 1 回呼び出され、変更されたアイテムを取得してインデックス登録します。

  • (省略可)close() メソッド。リポジトリをクリーンアップする必要がある場合は、close() メソッドをオーバーライドします。このメソッドは、コネクタのシャットダウン時に 1 回呼び出されます。

Repository オブジェクトの各メソッドにより、ApiOperation オブジェクトの一種が返されます。ApiOperation オブジェクトにより、単一または複数の形式でアクションが実行され、IndexingService.indexItem() 呼び出しでリポジトリの実際のインデックス登録を実行します。

カスタム構成パラメータを取得する

コネクタを構成する過程で、Configuration オブジェクトからいずれかのカスタム パラメータを取得する必要があります。このタスクは通常、Repository クラスの init() メソッドで実行します。

Configuration クラスには、構成から異なるデータ型を取得するメソッドがいくつかあります。各メソッドにより ConfigValue オブジェクトが返されます。その後、ConfigValue オブジェクトの get() メソッドを使用して実際の値を取得します。次のコード スニペット(FullTraversalSample からの抜粋)は、Configuration オブジェクトから単一のカスタム整数値を取得する方法を示しています。

FullTraversalSample.java
@Override
    public void init(RepositoryContext context) {
      log.info("Initializing repository");
      numberOfDocuments = Configuration.getInteger("sample.documentCount", 10).get();
    }

複数の値を含むパラメータを取得して解析するには、Configuration クラスのいずれかの型パーサーを使用してデータを個別のチャンクに解析します。次のコード スニペット(チュートリアル コネクタからの抜粋)は、getMultiValue メソッドを使用して GitHub リポジトリの名前のリストを取得しています。

GithubRepository.java
ConfigValue<List<String>> repos = Configuration.getMultiValue(
        "github.repos",
        Collections.emptyList(),
        Configuration.STRING_PARSER);

リスト走査を実行する

getIds() メソッドをオーバーライドして、リポジトリ内のすべてのレコードの ID とハッシュ値を取得します。getIds() メソッドはチェックポイントを受け取って処理します。チェックポイントは、プロセスが中断された場合に特定のアイテムからインデックス登録を再開する目的で使用します。

次に、getDoc() メソッドをオーバーライドして、Cloud Search インデックス登録キュー内の各アイテムを処理します。

アイテムの ID とハッシュ値を push する

getIds() をオーバーライドして、アイテムの ID と関連コンテンツのハッシュ値をリポジトリからフェッチします。その後、ID とハッシュ値のペアをパッケージ化して、Cloud Search インデックス登録キューに対する push 操作リクエストを作成します。通常、ルート(または親)の ID が最初に push され、続いて子の ID が push されます。こうしてアイテムの階層全体が処理されます。

getIds() メソッドはチェックポイント(インデックス登録する最後のアイテムを表します)を受け取って処理します。チェックポイントは、プロセスが中断された場合に特定のアイテムからインデックス登録を再開する目的で使用します。リポジトリ内のアイテムごとに、getIds() メソッド内で以下の手順を実行します。

  • 各アイテムの ID と関連ハッシュ値をリポジトリから取得する。
  • 各 ID とハッシュ値のペアを PushItems にパッケージ化する。
  • PushItemsgetIds() メソッドから返されるイテレータに結合する。なお、getIds() により実際に返されるのは CheckpointCloseableIterable であり、これは ApiOperation オブジェクトのイテレーションです。この各オブジェクトは RepositoryDoc で実行した API リクエスト(キューへのアイテムの push など)を表します。

次のコード スニペットは、各アイテムの ID とハッシュ値を取得して PushItems に挿入する方法を示しています。PushItems は、アイテムを Cloud Search インデックス登録キューに push する ApiOperation リクエストです。

ListTraversalSample.java
PushItems.Builder allIds = new PushItems.Builder();
    for (Map.Entry<Integer, Long> entry : this.documents.entrySet()) {
      String documentId = Integer.toString(entry.getKey());
      String hash = this.calculateMetadataHash(entry.getKey());
      PushItem item = new PushItem().setMetadataHash(hash);
      log.info("Pushing " + documentId);
      allIds.addPushItem(documentId, item);
    }

次のコード スニペットは、PushItems.Builder クラスを使用して、ID とハッシュ値を単一の push ApiOperation にパッケージ化する方法を示しています。

ListTraversalSample.java
ApiOperation pushOperation = allIds.build();
    CheckpointCloseableIterable<ApiOperation> iterator =
      new CheckpointCloseableIterableImpl.Builder<>(
          Collections.singletonList(pushOperation))
      .build();
    return iterator;

アイテムは、Cloud Search インデックス登録キューに push 後、さらに処理されます。

各アイテムを取得して処理する

getDoc() をオーバーライドして、Cloud Search インデックス登録キュー内の各アイテムを処理します。ソース リポジトリ内のアイテムには新規のアイテム、変更済みのアイテム、未変更のアイテムがあり、アイテムがもう存在しないこともあります。新規または変更済みの各アイテムを取得してインデックス登録します。ソース リポジトリにもう存在しないアイテムをインデックスから取り除きます。

getDoc() メソッドは、Google Cloud Search インデックス登録キューからアイテムを受け取って処理します。キュー内のアイテムごとに、getDoc() メソッド内で以下の手順を実行します。

  1. Cloud Search インデックス登録キュー内のアイテムの ID がリポジトリに存在するかどうかを確認し、存在しなければアイテムをインデックスから削除する。

  2. インデックス登録対象のアイテムのステータスをポーリングし、アイテムが未変更(ACCEPTED)の場合は何もしない。

  3. 変更済みまたは新規のアイテムをインデックス登録する:

    1. アクセス許可を設定する。
    2. インデックス登録するアイテムのメタデータを設定する。
    3. メタデータとアイテムを結合して、インデックス登録可能な 1 つの RepositoryDoc を作成する。
    4. RepositoryDoc を返す。

注: ListingConnector テンプレートは、getDoc() メソッドで null を返す処理をサポートしていません。null を返すと、NullPointerException. が発生します。

削除対象のアイテムを処理する

次のコード スニペットは、アイテムがリポジトリに存在するかどうか確認し、存在しない場合に削除する方法を示しています。

ListTraversalSample.java
String resourceName = item.getName();
    int documentId = Integer.parseInt(resourceName);

    if (!documents.containsKey(documentId)) {
      // Document no longer exists -- delete it
      log.info(() -> String.format("Deleting document %s", item.getName()));
      return ApiOperations.deleteItem(resourceName);
    }

なお、documents はリポジトリを表すデータ構造です。documentIDdocuments 内で見つからない場合は、該当アイテムをインデックスから削除するために APIOperations.deleteItem(resourceName) を返します。

未変更のアイテムを処理する

次のコード スニペットは、Cloud Search インデックス登録キュー内のアイテムのステータスをポーリングし、未変更のアイテムを処理する方法を示しています。

ListTraversalSample.java
String currentHash = this.calculateMetadataHash(documentId);
    if (this.canSkipIndexing(item, currentHash)) {
      // Document neither modified nor deleted, ack the push
      log.info(() -> String.format("Document %s not modified", item.getName()));
      PushItem pushItem = new PushItem().setType("NOT_MODIFIED");
      return new PushItems.Builder().addPushItem(resourceName, pushItem).build();
    }

未変更アイテムであるか確認するには、変更の可能性を示すアイテムのステータスとその他のメタデータを調べます。この例では、アイテムが変更されたかどうかを確認するために、メタデータであるハッシュを使用しています。

ListTraversalSample.java
/**
     * Checks to see if an item is already up to date
     *
     * @param previousItem Polled item
     * @param currentHash  Metadata hash of the current github object
     * @return PushItem operation
     */
    private boolean canSkipIndexing(Item previousItem, String currentHash) {
      if (previousItem.getStatus() == null || previousItem.getMetadata() == null) {
        return false;
      }
      String status = previousItem.getStatus().getCode();
      String previousHash = previousItem.getMetadata().getHash();
      return "ACCEPTED".equals(status)
          && previousHash != null
          && previousHash.equals(currentHash);
    }

アイテムへのアクセス許可を設定する

リポジトリは、アイテムにアクセスできるユーザーまたはグループを識別するためにアクセス制御リスト(ACL)を使用しています。ACL とは、アイテムにアクセスできるグループまたはユーザーの ID のリストです。

この ACL をデータソースに複製して、検索を実行したユーザーに、アクセス権を持つアイテムのみが表示されるようにする必要があります。同様に、アイテムをインデックス登録するときに、アイテムの ACL を含めてください。これは、Google Cloud Search がアイテムに適切なアクセスレベルを提供するために必要な情報です。

Content Connector SDK は、リポジトリの ACL をモデル化するために必要な一連の ACL クラスやメソッドを潤沢に提供しているため、ほとんどのリポジトリに対応できます。アイテムをインデックス登録するときは、リポジトリ内の各アイテムの ACL を分析して、Google Cloud Search の対応する ACL を作成する必要があります。リポジトリの ACL で ACL の継承といったコンセプトが用いられている場合、その ACL をモデル化するのは厄介な作業になるかもしれません。Google Cloud Search の ACL の詳細は、Google Cloud Search の ACL を参照してください。

注: Cloud Search の Indexing API がサポートしているのは単一ドメインの ACL であって、クロスドメインの ACL ではありません。原則として、ACL を使用する各アイテムへのアクセスを設定するには、Acl.Builder クラスを使用します。次のコード スニペット(フル走査のサンプルからの抜粋)は、検索を行う際に、すべてのユーザー、つまり「プリンシパル」(getCustomerPrincipal())がすべてのアイテムの「リーダー」(.setReaders())になることを許可しています。

FullTraversalSample.java
// Make the document publicly readable within the domain
    Acl acl = new Acl.Builder()
        .setReaders(Collections.singletonList(Acl.getCustomerPrincipal()))
        .build();

ACL について理解していないとデータソースの ACL を適切にモデル化することはできません。たとえば、あるファイル システムのファイルをインデックス登録するとき、そのファイル システムである種の継承モデルが用いられているために、子フォルダが親フォルダからアクセス権を継承する場合があります。ACL の継承をモデル化するためには、Google Cloud Search の ACL で解説している追加情報が必要です。

アイテムのメタデータを設定する

メタデータは Item オブジェクトに格納されます。Item の作成に必要な最低限の情報は、文字列型の一意の ID、アイテムタイプ、ACL、URL、アイテムのバージョンです。次のコード スニペットは、IndexingItemBuilder ヘルパークラスを使用して Item を作成する方法を示しています。

ListTraversalSample.java
// Url is required. Use google.com as a placeholder for this sample.
    String viewUrl = "https://www.google.com";

    // Version is required, set to current timestamp.
    byte[] version = Longs.toByteArray(System.currentTimeMillis());

    // Set metadata hash so queue can detect changes
    String metadataHash = this.calculateMetadataHash(documentId);

    // Using the SDK item builder class to create the document with
    // appropriate attributes. This can be expanded to include metadata
    // fields etc.
    Item item = IndexingItemBuilder.fromConfiguration(Integer.toString(documentId))
        .setItemType(IndexingItemBuilder.ItemType.CONTENT_ITEM)
        .setAcl(acl)
        .setSourceRepositoryUrl(IndexingItemBuilder.FieldOrValue.withValue(viewUrl))
        .setVersion(version)
        .setHash(metadataHash)
        .build();

インデックス登録可能なアイテムを作成する

アイテムのメタデータを設定すると、RepositoryDoc.Builder を使用して実際のインデックス登録可能なアイテムを作成できるようになります。次の例は、単一のインデックス登録可能なアイテムを作成する方法を示しています。

ListTraversalSample.java
// For this sample, content is just plain text
    String content = String.format("Hello world from sample doc %d", documentId);
    ByteArrayContent byteContent = ByteArrayContent.fromString("text/plain", content);

    // Create the fully formed document
    RepositoryDoc doc = new RepositoryDoc.Builder()
        .setItem(item)
        .setContent(byteContent, IndexingService.ContentFormat.TEXT)
        .build();

RepositoryDoc は、実際の IndexingService.indexItem() リクエストを実行する ApiOperation の一種です。

RepositoryDoc.Builder クラスの setRequestMode() メソッドを使用して、インデックス登録リクエストのモードを ASYNCHRONOUS または SYNCHRONOUS に指定することもできます。

ASYNCHRONOUS
非同期モードに設定すると、インデックス登録してから結果を得るまでのレイテンシが長くなり、インデックス登録リクエストに対する処理割り当て量の供給が増えます。非同期モードは、リポジトリ全体を最初にインデックス登録(バックフィル)するケースで使うことをおすすめします。
SYNCHRONOUS
同期モードに設定すると、インデックス登録してから結果を得るまでのレイテンシが短くなり、処理割り当て量の供給が制限されます。同期モードは、リポジトリの更新や変更をインデックス登録するケースで使うことをおすすめします。省略時のリクエスト モードはデフォルトで SYNCHRONOUS になります。

次のステップ

必要に応じて次の手順を行います。

  • (省略可)シャットダウンの前にリソースをすべて解放する close() メソッドを実装する。
  • (省略可)Content Connector SDK で ID コネクタを作成する

テンプレート クラスを使用してグラフ走査コネクタを作成する

Cloud Search インデックス登録キューの目的は、リポジトリ内の各アイテムの ID(および必要に応じてハッシュ値)を保持することです。グラフ走査コネクタは、Google Cloud Search インデックス登録キューにアイテム ID を push し、インデックス登録のためにそこから 1 つずつ取得します。Google Cloud Search はキューを維持管理し、キューの内容を比較することでアイテムのステータス(アイテムがリポジトリから削除済みかどうかなど)を確認します。Google Search インデックス登録キューの詳細については、Google Cloud Search インデックス登録キューをご覧ください。

インデックス登録の過程で、アイテムのコンテンツがデータ リポジトリからフェッチされ、すべての子アイテムの ID がキューに push されます。コネクタによる親 ID と子 ID の処理は、すべてのアイテムが処理されるまで再帰的に進行します。

このドキュメント セクションのコード スニペットは、GraphTraversalSample サンプルからの抜粋です。

コネクタのエントリ ポイントを実装する

コネクタのエントリ ポイントは main() メソッドです。このメソッドの主なタスクは、Application クラスのインスタンスを作成し、start() メソッドを起動してコネクタを実行することです。

application.start() を呼び出す前に、IndexingApplication.Builder クラスを使用して ListingConnector テンプレートをインスタンス化します。ListingConnector は、実装するメソッドを含む Repository オブジェクトを受け取って処理します。

次のコード スニペットは、ListingConnector とそれに関連する Repository をインスタンス化する方法を示しています。

GraphTraversalSample.java
/**
     * This sample connector uses the Cloud Search SDK template class for a graph
     * traversal connector.
     *
     * @param args program command line arguments
     * @throws InterruptedException thrown if an abort is issued during initialization
     */
    public static void main(String[] args) throws InterruptedException {
      Repository repository = new SampleRepository();
      IndexingConnector connector = new ListingConnector(repository);
      IndexingApplication application = new IndexingApplication.Builder(connector, args).build();
      application.start();
    }

バックグラウンドでは、コネクタの main() メソッドが Application.build を呼び出した後に、SDK が initConfig() メソッドを呼び出します。initConfig() メソッドは、次のタスクを実行します。

  1. Configuation.isInitialized() メソッドを呼び出して、Configuration がまだ初期化されていないことを確認します。
  2. Google 提供の Key-Value ペアで Configuration オブジェクトを初期化します。Configuration オブジェクト内の ConfigValue オブジェクトに各 Key-Value ペアが格納されます。

Repository インターフェースを実装する

Repository オブジェクトの唯一の目的は、リポジトリ アイテムを走査してインデックス登録することです。テンプレートを利用すると、Repository インターフェースの一部のメソッドをオーバーライドするだけでコンテンツ コネクタを作成できます。オーバーライドするメソッドは、使用するテンプレートと走査戦略によって異なります。ListingConnector の場合は、次のメソッドをオーバーライドします。

  • init() メソッド。データ リポジトリをセットアップして初期設定するには、init() メソッドをオーバーライドします。

  • getIds() メソッド。リポジトリ内のすべてのレコードの ID とハッシュ値を取得するには、getIds() メソッドをオーバーライドします。

  • getDoc() メソッド。インデックス内のアイテムを追加、更新、変更、削除するには、getDoc() メソッドをオーバーライドします。

  • (省略可)getChanges() メソッド。リポジトリが変更検出機能をサポートしている場合、getChanges() メソッドをオーバーライドします。このメソッドは、(構成で定義した)スケジュールに従い増分走査が行われるたびに 1 回呼び出され、変更されたアイテムを取得してインデックス登録します。

  • (省略可)close() メソッド。リポジトリをクリーンアップする必要がある場合は、close() メソッドをオーバーライドします。このメソッドは、コネクタのシャットダウン時に 1 回呼び出されます。

Repository オブジェクトの各メソッドにより、ApiOperation オブジェクトの一種が返されます。ApiOperation オブジェクトにより、単一または複数の形式でアクションが実行され、IndexingService.indexItem() 呼び出しでリポジトリの実際のインデックス登録を実行します。

カスタム構成パラメータを取得する

コネクタを構成する過程で、Configuration オブジェクトからいずれかのカスタム パラメータを取得する必要があります。このタスクは通常、Repository クラスの init() メソッドで実行します。

Configuration クラスには、構成から異なるデータ型を取得するメソッドがいくつかあります。各メソッドにより ConfigValue オブジェクトが返されます。その後、ConfigValue オブジェクトの get() メソッドを使用して実際の値を取得します。次のコード スニペット(FullTraversalSample からの抜粋)は、Configuration オブジェクトから単一のカスタム整数値を取得する方法を示しています。

FullTraversalSample.java
@Override
    public void init(RepositoryContext context) {
      log.info("Initializing repository");
      numberOfDocuments = Configuration.getInteger("sample.documentCount", 10).get();
    }

複数の値を含むパラメータを取得して解析するには、Configuration クラスのいずれかの型パーサーを使用してデータを個別のチャンクに解析します。次のコード スニペット(チュートリアル コネクタからの抜粋)は、getMultiValue メソッドを使用して GitHub リポジトリの名前のリストを取得しています。

GithubRepository.java
ConfigValue<List<String>> repos = Configuration.getMultiValue(
        "github.repos",
        Collections.emptyList(),
        Configuration.STRING_PARSER);

グラフ走査を実行する

getIds() メソッドをオーバーライドして、リポジトリ内のすべてのレコードの ID とハッシュ値を取得します。getIds() メソッドはチェックポイントを受け取って処理します。チェックポイントは、プロセスが中断された場合に特定のアイテムからインデックス登録を再開する目的で使用します。

次に、getDoc() メソッドをオーバーライドして、Cloud Search インデックス登録キュー内の各アイテムを処理します。

アイテムの ID とハッシュ値を push する

getIds() をオーバーライドして、アイテムの ID と関連コンテンツのハッシュ値をリポジトリからフェッチします。その後、ID とハッシュ値のペアをパッケージ化して、Cloud Search インデックス登録キューに対する push 操作リクエストを作成します。通常、ルート(または親)の ID が最初に push され、続いて子の ID が push されます。こうしてアイテムの階層全体が処理されます。

getIds() メソッドはチェックポイント(インデックス登録する最後のアイテムを表します)を受け取って処理します。チェックポイントは、プロセスが中断された場合に特定のアイテムからインデックス登録を再開する目的で使用します。リポジトリ内のアイテムごとに、getIds() メソッド内で以下の手順を実行します。

  • 各アイテムの ID と関連ハッシュ値をリポジトリから取得する。
  • 各 ID とハッシュ値のペアを PushItems にパッケージ化する。
  • PushItemsgetIds() メソッドから返されるイテレータに結合する。なお、getIds() により実際に返されるのは CheckpointCloseableIterable であり、これは ApiOperation オブジェクトのイテレーションです。この各オブジェクトは RepositoryDoc で実行した API リクエスト(キューへのアイテムの push など)を表します。

次のコード スニペットは、各アイテムの ID とハッシュ値を取得して PushItems に挿入する方法を示しています。PushItems は、アイテムを Cloud Search インデックス登録キューに push する ApiOperation リクエストです。

GraphTraversalSample.java
PushItems.Builder allIds = new PushItems.Builder();
    PushItem item = new PushItem();
    allIds.addPushItem("root", item);

次のコード スニペットは、PushItems.Builder クラスを使用して、ID とハッシュ値を単一の push ApiOperation にパッケージ化する方法を示しています。

GraphTraversalSample.java
ApiOperation pushOperation = allIds.build();
    CheckpointCloseableIterable<ApiOperation> iterator =
      new CheckpointCloseableIterableImpl.Builder<>(
          Collections.singletonList(pushOperation))
      .build();

アイテムは、Cloud Search インデックス登録キューに push 後、さらに処理されます。

各アイテムを取得して処理する

getDoc() をオーバーライドして、Cloud Search インデックス登録キュー内の各アイテムを処理します。ソース リポジトリ内のアイテムには新規のアイテム、変更済みのアイテム、未変更のアイテムがあり、アイテムがもう存在しないこともあります。新規または変更済みの各アイテムを取得してインデックス登録します。ソース リポジトリにもう存在しないアイテムをインデックスから取り除きます。

getDoc() メソッドは、Google Search インデックス登録キューからアイテムを受け取って処理します。キュー内のアイテムごとに、getDoc() メソッド内で以下の手順を実行します。

  1. Cloud Search インデックス登録キュー内のアイテムの ID がリポジトリに存在するかどうかを確認し、存在しなければアイテムをインデックスから削除する。存在する場合は、次の手順に進む。

  2. 変更済みまたは新規のアイテムをインデックス登録する:

    1. アクセス許可を設定する。
    2. インデックス登録するアイテムのメタデータを設定する。
    3. メタデータとアイテムを結合して、インデックス登録可能な 1 つの RepositoryDoc を作成する。
    4. 子の ID を Cloud Search インデックス登録キューに入れて処理を続ける。
    5. RepositoryDoc を返す。

削除対象のアイテムを処理する

次のコード スニペットは、アイテムがインデックスに存在するかどうか確認し、存在しない場合に削除する方法を示しています。

GraphTraversalSample.java
String resourceName = item.getName();
    if (documentExists(resourceName)) {
      return buildDocumentAndChildren(resourceName);
    }
    // Document doesn't exist, delete it
    log.info(() -> String.format("Deleting document %s", resourceName));
    return ApiOperations.deleteItem(resourceName);

アイテムへのアクセス許可を設定する

リポジトリは、アイテムにアクセスできるユーザーまたはグループを識別するためにアクセス制御リスト(ACL)を使用しています。ACL とは、アイテムにアクセスできるグループまたはユーザーの ID のリストです。

この ACL をデータソースに複製して、検索を実行したユーザーに、アクセス権を持つアイテムのみが表示されるようにする必要があります。同様に、アイテムをインデックス登録するときに、アイテムの ACL を含めてください。これは、Google Cloud Search がアイテムに適切なアクセスレベルを提供するために必要な情報です。

Content Connector SDK は、リポジトリの ACL をモデル化するために必要な一連の ACL クラスやメソッドを潤沢に提供しているため、ほとんどのリポジトリに対応できます。アイテムをインデックス登録するときは、リポジトリ内の各アイテムの ACL を分析して、Google Cloud Search の対応する ACL を作成する必要があります。リポジトリの ACL で ACL の継承といったコンセプトが用いられている場合、その ACL をモデル化するのは厄介な作業になるかもしれません。Google Cloud Search の ACL の詳細は、Google Cloud Search の ACL を参照してください。

注: Cloud Search の Indexing API がサポートしているのは単一ドメインの ACL であって、クロスドメインの ACL ではありません。原則として、ACL を使用する各アイテムへのアクセスを設定するには、Acl.Builder クラスを使用します。次のコード スニペット(フル走査のサンプルからの抜粋)は、検索を行う際に、すべてのユーザー、つまり「プリンシパル」(getCustomerPrincipal())がすべてのアイテムの「リーダー」(.setReaders())になることを許可しています。

FullTraversalSample.java
// Make the document publicly readable within the domain
    Acl acl = new Acl.Builder()
        .setReaders(Collections.singletonList(Acl.getCustomerPrincipal()))
        .build();

ACL について理解していないとデータソースの ACL を適切にモデル化することはできません。たとえば、あるファイル システムのファイルをインデックス登録するとき、そのファイル システムである種の継承モデルが用いられているために、子フォルダが親フォルダからアクセス権を継承する場合があります。ACL の継承をモデル化するためには、Google Cloud Search の ACL で解説している追加情報が必要です。

アイテムのメタデータを設定する

メタデータは Item オブジェクトに格納されます。Item の作成に必要な最低限の情報は、文字列型の一意の ID、アイテムタイプ、ACL、URL、アイテムのバージョンです。次のコード スニペットは、IndexingItemBuilder ヘルパークラスを使用して Item を作成する方法を示しています。

GraphTraversalSample.java
// Url is required. Use google.com as a placeholder for this sample.
    String viewUrl = "https://www.google.com";

    // Version is required, set to current timestamp.
    byte[] version = Longs.toByteArray(System.currentTimeMillis());

    // Using the SDK item builder class to create the document with
    // appropriate attributes. This can be expanded to include metadata
    // fields etc.
    Item item = IndexingItemBuilder.fromConfiguration(documentId)
        .setItemType(IndexingItemBuilder.ItemType.CONTENT_ITEM)
        .setAcl(acl)
        .setSourceRepositoryUrl(IndexingItemBuilder.FieldOrValue.withValue(viewUrl))
        .setVersion(version)
        .build();

インデックス登録可能なアイテムを作成する

アイテムのメタデータを設定すると、RepositoryDoc.Builder を使用して実際のインデックス登録可能なアイテムを作成できるようになります。次の例は、単一のインデックス登録可能なアイテムを作成する方法を示しています。

GraphTraversalSample.java
// For this sample, content is just plain text
    String content = String.format("Hello world from sample doc %s", documentId);
    ByteArrayContent byteContent = ByteArrayContent.fromString("text/plain", content);

    RepositoryDoc.Builder docBuilder = new RepositoryDoc.Builder()
        .setItem(item)
        .setContent(byteContent, IndexingService.ContentFormat.TEXT);

RepositoryDoc は、実際の IndexingService.indexItem() リクエストを実行する ApiOperation の一種です。

RepositoryDoc.Builder クラスの setRequestMode() メソッドを使用して、インデックス登録リクエストのモードを ASYNCHRONOUS または SYNCHRONOUS に指定することもできます。

ASYNCHRONOUS
非同期モードに設定すると、インデックス登録してから結果を得るまでのレイテンシが長くなり、インデックス登録リクエストに対する処理割り当て量の供給が増えます。非同期モードは、リポジトリ全体を最初にインデックス登録(バックフィル)するケースで使うことをおすすめします。
SYNCHRONOUS
同期モードに設定すると、インデックス登録してから結果を得るまでのレイテンシが短くなり、処理割り当て量の供給が制限されます。同期モードは、リポジトリの更新や変更をインデックス登録するケースで使うことをおすすめします。省略時のリクエスト モードはデフォルトで SYNCHRONOUS になります。

子の ID を Cloud Search インデックス登録キューに入れる

次のコード スニペットは、現在処理中の親アイテムの子の ID をキューに入れて処理する方法を示しています。これらの ID は、親アイテムのインデックス登録後に処理されます。

GraphTraversalSample.java
// Queue the child nodes to visit after indexing this document
    Set<String> childIds = getChildItemNames(documentId);
    for (String id : childIds) {
      log.info(() -> String.format("Pushing child node %s", id));
      PushItem pushItem = new PushItem();
      docBuilder.addChildId(id, pushItem);
    }

    RepositoryDoc doc = docBuilder.build();

次のステップ

必要に応じて次の手順を行います。

  • (省略可)シャットダウンの前にリソースをすべて解放する close() メソッドを実装する。
  • (省略可)Identity Connector SDK で ID コネクタを作成する

REST API を使用してコンテンツ コネクタを作成する

以下のセクションでは、REST API を使用してコンテンツ コネクタを作成する方法を説明します。

使用する走査戦略を決める

コンテンツ コネクタの主なファンクションは、リポジトリを走査してそのデータをインデックス登録することです。リポジトリ内のデータの規模と配置に基づいて走査戦略を実装してください。よく使われる走査戦略は以下の 3 つです。

フル走査戦略

リポジトリ全体をスキャンして、すべてのアイテムを無分別にインデックス登録する戦略です。フル走査は、リポジトリの規模が小さく、インデックス登録するたびに全体を走査してもオーバーヘッドを許容できる場合によく使われる戦略です。

フル走査戦略は、概ね静的で階層構造を持たないデータを含む小規模なリポジトリに向いています。変更検出が困難なリポジトリや変更検出機能をサポートしていないリポジトリで使用することもあります。

リスト走査戦略

すべての子ノードを含むリポジトリ全体をスキャンして各アイテムのステータスを確認した後、2 回目のパスで前回のインデックス登録以降に作成または更新されたアイテムのみをインデックス登録する戦略です。リスト走査戦略は、インデックスを更新するたびに全体を走査しなくてもよい場合に、既存のインデックスを増分更新するためによく使われる戦略です。

リスト走査戦略は、変更検出が困難なリポジトリや変更検出機能をサポートしていないリポジトリで、データが階層化されておらず、扱うデータセットが非常に大規模であるようなケースに向いています。

グラフ走査戦略

親ノード全体をスキャンして各アイテムのステータスを確認した後、2 回目のパスで前回のインデックス登録以降に作成または更新されたルートノード内のアイテムのみをインデックス登録し、その後、該当するすべての子 ID を引き渡し、作成または更新された子ノード内のアイテムをインデックス登録する戦略です。コネクタは、該当するアイテムがすべて処理されるまで、すべての子ノードを再帰的にスキャンします。この種の走査は、通常、ID をすべてリストすることが現実的でない階層的なリポジトリに対して使われます。

グラフ走査戦略は、一連のディレクトリやウェブページのような階層的なデータに対してクロール操作でデータを収集するケースに向いています。

走査戦略を実装しアイテムをインデックス登録する

Cloud Search API では Google Cloud Search のインデックス登録可能なすべての要素を「アイテム」と呼びます。たとえば、ファイル、フォルダ、CSV ファイルの行、データベース レコードなどがアイテムであるとみなされます。

スキーマを登録した後、次の方法で所定のインデックスを完成できます。

  1. (省略可)items.upload を使用して、インデックス登録用の 100 KiB を超えるファイルをアップロードします。小さいファイルの場合は、items.index を使用し、コンテンツを inlineContent として埋め込みます。

  2. (省略可)media.upload を使用して、インデックス登録用のメディア ファイルをアップロードします。

  3. items.index を使用してアイテムをインデックス登録します。たとえば、スキーマで movie スキーマのオブジェクト定義を使用している場合、単一のアイテムに関するインデックス登録リクエストは次のようになります。

    {
          "name": "datasource/<data_source_id>/items/titanic",
          "acl": {
            "readers": [
              {
                "gsuitePrincipal": {
                  "gsuiteDomain": true
                }
              }
            ]
          },
          "metadata": {
            "title": "Titanic",
            "viewUrl": "http://www.imdb.com/title/tt2234155/?ref_=nv_sr_1",
            "objectType": "movie"
          },
          "structuredData": {
            "object": {
              "properties": [
                {
                  "name": "movieTitle",
                  "textValues": {
                    "values": [
                      "Titanic"
                    ]
                  }
                },
                {
                  "name": "releaseDate",
                  "dateValues": {
                    "values": [
                      {
                        "year": 1997,
                        "month": 12,
                        "day": 19
                      }
                    ]
                  }
                },
                {
                  "name": "actorName",
                  "textValues": {
                    "values": [
                      "Leonardo DiCaprio",
                      "Kate Winslet",
                      "Billy Zane"
                    ]
                  }
                },
                {
                  "name": "genre",
                  "enumValues": {
                    "values": [
                      "Drama",
                      "Action"
                    ]
                  }
                },
                {
                  "name": "userRating",
                  "integerValues": {
                    "values": [
                      8
                    ]
                  }
                },
                {
                  "name": "mpaaRating",
                  "textValues": {
                    "values": [
                      "PG-13"
                    ]
                  }
                },
                {
                  "name": "duration",
                  "textValues": {
                    "values": [
                      "3 h 14 min"
                    ]
                  }
                }
              ]
            }
          },
          "content": {
            "inlineContent": "A seventeen-year-old aristocrat falls in love with a kind but poor artist aboard the luxurious, ill-fated R.M.S. Titanic.",
            "contentFormat": "TEXT"
          },
          "version": "01",
          "itemType": "CONTENT_ITEM"
        }
        
  4. (省略可)items.get 呼び出しを使用して、アイテムがインデックス登録されていることを確認します。

フル走査を実行するには、リポジトリ全体を定期的に繰り返しインデックス登録します。リスト走査またはグラフ走査を実行するには、リポジトリの変更を処理するコードを実装する必要があります。

リポジトリの変更を処理する

リポジトリ内の各アイテムを定期的に収集してインデックス登録することで完全な形のインデックスを作成できます。完全な形のインデックスの作成は、インデックスを最新状態に維持するには効果的ですが、リポジトリの規模が大きい場合や階層構造を持つ場合にコストがかかる可能性があります。

インデックス登録呼び出しを使用してリポジトリ全体を毎回繰り返しインデックス登録する代わりに、Google Cloud インデックス登録キューを変更追跡メカニズムとして使用し、変更されたアイテムだけをインデックス登録する方法もあります。items.push リクエストを使用してアイテムをこのキューに push した後にポーリングして更新を行うことができます。Google Cloud インデックス登録キューの詳細は、Google Cloud インデックス登録キューを参照してください。

Cloud Search REST API の詳細については、Cloud Search API をご覧ください。