すべてのプロダクト
Search
ドキュメントセンター

Tablestore:検索インデックスのクイックスタート

最終更新日:Jul 31, 2026

検索インデックスを使用すると、プライマリキー以外の列や複数の条件に基づいてデータをクエリできます。このトピックでは、製品データを例として、Tablestore SDK for Java を使用してデータテーブルと検索インデックスを作成し、データを書き込み、Term クエリを実行する方法を説明します。

事前準備

  • Tablestore を有効化し、インスタンスを作成します。詳細については、「サービスのアクティブ化とインスタンスの作成」をご参照ください。

  • Tablestore SDK for Java をインストールし、クライアントを初期化して、SyncClient インスタンスを取得します。詳細については、「Java SDK」をご参照ください。

操作手順

この例では、example_table という名前のデータテーブルと example_index という名前の検索インデックスを作成します。検索インデックスの準備ができた後、3 つの製品行を書き込み、category 列の値が books である行にクエリを実行します。

次の手順のサンプルメソッドを、クライアントを初期化した Java アプリケーションに追加します。その後、次の順序でメソッドを呼び出します。

private static void runQuickStart(SyncClient client)
        throws InterruptedException {
    String tableName = "example_table";
    String indexName = "example_index";

    createTable(client, tableName);
    createSearchIndex(client, tableName, indexName);
    waitUntilSearchIndexIsReady(client, tableName, indexName);
    putSampleRows(client, tableName);

    SearchResponse response =
            waitUntilBooksAreQueryable(client, tableName, indexName);
    System.out.println("Total count: " + response.getTotalCount());
    System.out.println("Rows: " + response.getRows());
}

ステップ 1:データテーブルの作成

データテーブルの検索インデックスを作成するには、最大バージョン数を 1 に設定する必要があります。また、データが期限切れにならないように、データテーブルの Time to Live (TTL) を -1 に設定するか、データ更新を無効にする必要があります。この例では、最大バージョン数は 1 に、TTL は -1 に設定されています。

private static void createTable(
        SyncClient client, String tableName) {
    TableMeta tableMeta = new TableMeta(tableName);
    tableMeta.addPrimaryKeyColumn(
            new PrimaryKeySchema(
                    "product_id", PrimaryKeyType.STRING));

    TableOptions tableOptions = new TableOptions();
    tableOptions.setTimeToLive(-1);
    tableOptions.setMaxVersions(1);

    client.createTable(
            new CreateTableRequest(tableMeta, tableOptions));
}

ステップ 2:検索インデックスの作成

category および price 属性列にインデックスフィールドを作成します。 インデックスフィールドの名前とデータ型は、データテーブルの対応する属性列のものと同じである必要があります。

private static void createSearchIndex(
        SyncClient client, String tableName, String indexName) {
    IndexSchema indexSchema = new IndexSchema();
    indexSchema.setFieldSchemas(Arrays.asList(
            new FieldSchema("category", FieldType.KEYWORD),
            new FieldSchema("price", FieldType.LONG)));

    CreateSearchIndexRequest request =
            new CreateSearchIndexRequest();
    request.setTableName(tableName);
    request.setIndexName(indexName);
    request.setIndexSchema(indexSchema);
    client.createSearchIndex(request);
}

検索インデックスは非同期に作成されます。インデックスステータスがRUNNINGに、同期フェーズがINCRに変わるまで待ってから、データをクエリしてください。

private static final int RETRY_ATTEMPTS = 90;
private static final long RETRY_INTERVAL_MILLIS = 1_000L;

private static void waitUntilSearchIndexIsReady(
        SyncClient client, String tableName, String indexName)
        throws InterruptedException {
    for (int attempt = 1; attempt <= RETRY_ATTEMPTS; attempt++) {
        DescribeSearchIndexRequest request =
                new DescribeSearchIndexRequest();
        request.setTableName(tableName);
        request.setIndexName(indexName);
        request.setIncludeSyncStat(true);

        DescribeSearchIndexResponse response =
                client.describeSearchIndex(request);
        if (response.getIndexStatus() != null
                && response.getIndexStatus().indexStatusEnum
                == DescribeSearchIndexResponse.IndexStatusEnum.RUNNING
                && response.getSyncStat() != null
                && response.getSyncStat().getSyncPhase()
                == SyncStat.SyncPhase.INCR) {
            return;
        }
        Thread.sleep(RETRY_INTERVAL_MILLIS);
    }
    throw new IllegalStateException(
            "Search index did not become ready before timeout.");
}

ステップ 3:サンプルデータの書き込み

3 つの商品行を作成します。product_id 列は主キー列です。category 列と price 列は属性列です。

private static void putSampleRows(
        SyncClient client, String tableName) {
    putProduct(client, tableName, "product-001", "books", 89L);
    putProduct(client, tableName, "product-002", "books", 129L);
    putProduct(client, tableName, "product-003", "devices", 599L);
}

private static void putProduct(
        SyncClient client,
        String tableName,
        String productId,
        String category,
        long price) {
    PrimaryKey primaryKey =
            PrimaryKeyBuilder.createPrimaryKeyBuilder()
                    .addPrimaryKeyColumn(
                            "product_id",
                            PrimaryKeyValue.fromString(productId))
                    .build();

    RowPutChange rowPutChange =
            new RowPutChange(tableName, primaryKey);
    rowPutChange.addColumn(
            "category", ColumnValue.fromString(category));
    rowPutChange.addColumn(
            "price", ColumnValue.fromLong(price));
    client.putRow(new PutRowRequest(rowPutChange));
}

ステップ 4:データのクエリ

term クエリを実行して、category 列の値が books である行を検索します。 検索インデックスへのデータ同期には少し時間がかかります。 サンプルコードは、結果の準備ができていない場合にクエリを再試行します。

private static SearchResponse waitUntilBooksAreQueryable(
        SyncClient client, String tableName, String indexName)
        throws InterruptedException {
    for (int attempt = 1; attempt <= RETRY_ATTEMPTS; attempt++) {
        SearchResponse response =
                queryBooks(client, tableName, indexName);
        if (response.isAllSuccess()
                && response.getTotalCount() == 2L
                && response.getRows().size() == 2) {
            return response;
        }
        Thread.sleep(RETRY_INTERVAL_MILLIS);
    }
    throw new IllegalStateException(
            "Sample rows were not queryable before timeout.");
}

private static SearchResponse queryBooks(
        SyncClient client, String tableName, String indexName) {
    TermQuery termQuery = new TermQuery();
    termQuery.setFieldName("category");
    termQuery.setTerm(ColumnValue.fromString("books"));

    SearchQuery searchQuery = new SearchQuery();
    searchQuery.setQuery(termQuery);
    searchQuery.setLimit(10);
    searchQuery.setTrackTotalCount(
            SearchQuery.TRACK_TOTAL_COUNT);

    SearchRequest.ColumnsToGet columnsToGet =
            new SearchRequest.ColumnsToGet();
    columnsToGet.setReturnAll(true);

    SearchRequest request =
            new SearchRequest(tableName, indexName, searchQuery);
    request.setColumnsToGet(columnsToGet);
    return client.search(request);
}

一致した行の総数と返された行数の両方が 2 の場合、クエリは成功です。

リソースのクリーンアップ

サンプルリソースが不要になった場合は、データテーブルを削除する前に検索インデックスを削除します。

DeleteSearchIndexRequest deleteIndexRequest =
        new DeleteSearchIndexRequest();
deleteIndexRequest.setTableName("example_table");
deleteIndexRequest.setIndexName("example_index");
client.deleteSearchIndex(deleteIndexRequest);

client.deleteTable(new DeleteTableRequest("example_table"));
client.shutdown();

次のステップ

  • 検索インデックスの仕組み、ユースケース、制限事項については、「検索インデックス」をご参照ください。

  • インデックスの並べ替え、TTL、仮想列、およびその他のインデックス機能については、「検索インデックスの作成」をご参照ください。

  • 他のクエリタイプ、およびクエリ結果の並べ替え、集計、または重複排除の方法については、「データクエリ」をご参照ください。