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

Tablestore:シナリオ

最終更新日:Dec 28, 2024

セカンダリインデックス機能を使用すると、指定した列にインデックスを作成できます。生成されたインデックステーブルのデータは、指定されたインデックスキー列に基づいてソートされます。データテーブルに書き込まれたすべてのデータは、インデックステーブルに自動的に同期されます。データテーブルにデータを書き込んだ後、データテーブル用に作成されたインデックステーブルからデータをクエリできます。これにより、クエリの効率が向上します。

サンプルシナリオ

このトピックでは、セカンダリインデックス機能を使用して通話記録をクエリする方法について説明します。通話が完了すると、通話に関する情報がデータテーブルに記録されます。

次のセクションでは、データテーブルのプライマリキー列と事前定義された列について説明します。

  • CellNumber列とStartTime列は、データテーブルのプライマリキー列として使用されます。CellNumber列の各値は発信番号を示し、StartTime列の各値は通話の開始時刻を示します。

  • CalledNumber、Duration、およびBaseStationNumber列は、データテーブルの事前定義された列として使用されます。CalledNumber列の各値は着信番号を示し、Duration列の各値は通話時間を示し、BaseStationNumber列の各値は基地局番号を示します。

次の表に、データテーブルのサンプルデータを示します。Tablestoreのワイドカラムモデルは、データテーブルの行をプライマリキーに基づいてソートし、GetRange操作を提供してデータをクエリします。

CellNumber

StartTime (UNIXタイムスタンプ)

CalledNumber

Duration

BaseStationNumber

123456

1532574644

654321

60

1

234567

1532574714

765432

10

1

234567

1532574734

123456

20

3

345678

1532574795

123456

5

2

345678

1532574861

123456

100

2

456789

1532584054

345678

200

3

ビジネス要件に基づいて、データテーブル、グローバルセカンダリインデックス、またはローカルセカンダリインデックスを使用して、次のクエリを実行できます。

  • CellNumber列の値が234567である行をクエリします。

  • CalledNumber列の値が123456である行をクエリします。

  • BaseStationNumber列の値が2で、StartTime列の値が1532574740である行をクエリします。

  • BaseStationNumber列の値が3で、StartTime列の値が1532574861から1532584054の範囲である行のDuration列の値をクエリします。

  • 基地局3によって転送されたすべての通話の合計、平均、最大、および最小通話時間をクエリします。StartTime列の値は1532574861から1532584054の範囲です。

  • CellNumber列の値が456789で、CalledNumber列の値が345678である行をクエリします。

データクエリ

クエリ要件に基づいて、適切な方法を選択してデータをクエリできます。

方法

次の表に、さまざまなクエリを実装する方法を示します。

重要
  • データテーブルとセカンダリインデックステーブルの作成に使用されるサンプルコードの詳細については、「付録:データテーブルとセカンダリインデックステーブルを作成するためのサンプルコード」を参照してください。

    データテーブルを作成したら、サンプルデータをデータテーブルに書き込む必要があります。データテーブルのデータは、データテーブル用に作成されたインデックステーブルに自動的に同期されます。データの書き込み方法の詳細については、「データの書き込み」を参照してください。

  • Tablestoreは、インデックスキー列として指定されていないデータテーブルのプライマリキー列を、データテーブル用に作成されたインデックステーブルに自動的に追加します。データテーブルのプライマリキー列とインデックスキー列は、インデックステーブルのプライマリキー列として使用されます。

  • ローカルセカンダリインデックスを使用する場合、インデックステーブルの最初のプライマリキー列は、インデックステーブルが作成されるデータテーブルの最初のプライマリキー列と同じである必要があります。

クエリ

方法

CellNumber列の値が234567である行をクエリする

GetRange操作を直接呼び出して、データテーブルをスキャンできます。

CalledNumber列の値が123456である行をクエリする

CalledNumber列に基づいてインデックステーブルを作成し、GetRange操作を呼び出してインデックステーブルをスキャンできます。

BaseStationNumber列の値が2で、StartTime列の値が1532574740である行をクエリする

BaseStationNumber列とStartTime列に基づいてインデックステーブルを作成し、インデックスタイプがグローバルセカンダリインデックスであるインデックステーブルをスキャンするためにGetRange操作を呼び出すことができます。

BaseStationNumber列の値が3で、StartTime列の値が1532574861から1532584054の範囲である行のDuration列の値をクエリする

BaseStationNumber列とStartTime列に基づいてインデックステーブルを作成し、Duration列の値のみが返されるように指定してから、インデックスタイプがグローバルセカンダリインデックスであるインデックステーブルをスキャンするためにGetRange操作を呼び出すことができます。

データテーブルからDuration列の値を手動でクエリするか、Duration列をインデックステーブルの属性列として指定できます。

基地局3によって転送され、開始時刻が1532574861から1532584054の範囲であるすべての通話の合計、平均、最大、および最小通話時間をクエリするには、このクエリ方法も使用できます。次に、Duration列で集計を実行して最終結果を取得できます。

説明

クライアント側の計算なしでSQLステートメントを実行して結果を取得することもできます。詳細については、「データのクエリ」を参照してください。

CellNumber列の値が456789で、CalledNumber列の値が345678である行をクエリする

CellNumber列とCalledNumber列に基づいてインデックステーブルを作成し、Duration列とBaseStationNumber列をインデックステーブルの属性列として指定してから、インデックスタイプがローカルセカンダリインデックスであるインデックステーブルをスキャンするためにGetRange操作を呼び出すことができます。

CellNumber列の値が234567である行をクエリする

CellNumber列は、データテーブルのプライマリキー列です。したがって、GetRange操作を直接呼び出してデータテーブルをスキャンし、クエリ条件を満たす行を取得できます。

この場合、CellNumber列の最大値と最小値の両方を234567に設定し、StartTime列の最小値と最大値を0とINT_MAXに設定できます。

サンプルコード:

// サンプルコードのcellNumberパラメーターは、データテーブルのCellNumber列に対応します。
private static void getRangeFromMainTable(SyncClient client, long cellNumber){
    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(TABLE_NAME);

    // 開始プライマリキー列を指定します。
    PrimaryKeyBuilder startPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromLong(cellNumber));
    startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromLong(0));
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKeyBuilder.build());

    // 終了プライマリキー列を指定します。
    PrimaryKeyBuilder endPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromLong(cellNumber));
    endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MAX);
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endPrimaryKeyBuilder.build());

    rangeRowQueryCriteria.setMaxVersions(1);

    String strNum = String.format("%d", cellNumber);
    System.out.println("セル番号" + strNum + "は次の通話を発信します:");
    while (true) {
        GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
        for (Row row : getRangeResponse.getRows()) {
            System.out.println(row);
        }

        // nextStartPrimaryKeyの値がnullでない場合は、データの読み取りを続けます。
        if (getRangeResponse.getNextStartPrimaryKey() != null) {
            rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
        } else {
            break;
        }
    }
}

CalledNumber列の値が123456である行をクエリする

このクエリは、データテーブルの事前定義された列であるCalledNumber列の値に基づいて条件を指定します。データテーブルから直接クエリすることはできません。CalledNumber列に基づいてIndexOnBeCalledNumberという名前のインデックステーブルを作成し、CalledNumber列をインデックステーブルのプライマリキー列として指定してから、GetRange操作を呼び出してインデックステーブルをスキャンし、クエリ条件を満たす行を取得する必要があります。

インデックステーブルの最初のプライマリキー列は、データテーブルの最初のプライマリキー列とは異なります。したがって、インデックスタイプはグローバルセカンダリインデックスです。

インデックステーブルのデータ

次の表に、IndexOnBeCalledNumberインデックステーブルのデータを示します。

PK0

PK1

PK2

CalledNumber

CellNumber

StartTime

123456

234567

1532574734

123456

345678

1532574795

123456

345678

1532574861

345678

456789

1532584054

654321

123456

1532574644

765432

234567

1532574714

GetRange操作を呼び出してデータをクエリするときに、CalledNumber列の最大値と最小値の両方を123456に設定し、CellNumber列とStartTime列の最小値をINT_MINに設定し、CellNumber列とStartTime列の最大値をINT_MAXに設定できます。サンプルコード:

// サンプルコードのcalledNumberパラメーターは、インデックステーブルのCalledNumber列に対応します。
private static void getRangeFromIndexTable(SyncClient client, long calledNumber) {
    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(INDEX0_NAME);

    // 開始プライマリキー列を指定します。
    PrimaryKeyBuilder startPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    startPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.fromLong(calledNumber));
    startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MIN);
    startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MIN);
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKeyBuilder.build());

    // 終了プライマリキー列を指定します。
    PrimaryKeyBuilder endPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    endPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.fromLong(calledNumber));
    endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MAX);
    endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MAX);
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endPrimaryKeyBuilder.build());

    rangeRowQueryCriteria.setMaxVersions(1);

    String strNum = String.format("%d", calledNumber);
    System.out.println("セル番号" + strNum + "は次の番号から着信されています:");
    while (true) {
        GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
        for (Row row : getRangeResponse.getRows()) {
            System.out.println(row);
        }

        // nextStartPrimaryKeyの値がnullでない場合は、データの読み取りを続けます。
        if (getRangeResponse.getNextStartPrimaryKey() != null) {
            rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
        } else {
            break;
        }
    }
}

BaseStationNumber列の値が2で、StartTime列の値が1532574740である行をクエリするBaseStationNumber列の値が2で、StartTime列の値が1532574740である行をクエリする

このクエリは、BaseStationNumber列とStartTime列の値に基づいて条件を指定します。BaseStationNumber列は、データテーブルの事前定義された列です。データテーブルから直接クエリすることはできません。BaseStationNumber列とStartTime列に基づいてIndexOnBaseStation1という名前のインデックステーブルを作成し、BaseStationNumber列とStartTime列をインデックステーブルのプライマリキー列として指定してから、GetRange操作を呼び出してインデックステーブルをスキャンし、クエリ条件を満たす行を取得する必要があります。

インデックステーブルの最初のプライマリキー列は、データテーブルの最初のプライマリキー列とは異なります。したがって、インデックスタイプはグローバルセカンダリインデックスです。

インデックステーブルのデータ

次の表に、IndexOnBaseStation1インデックステーブルのデータを示します。

PK0

PK1

PK2

BaseStationNumber

StartTime

CellNumber

1

1532574644

123456

1

1532574714

234567

2

1532574795

345678

2

1532574861

345678

3

1532574734

234567

3

1532584054

456789

GetRange操作を呼び出してデータをクエリするときに、BaseStationNumber列の最大値と最小値の両方を2に設定し、StartTime列の最小値と最大値を1532574740とINT_MAXに設定し、CellNumber列の最小値と最大値をINT_MINとINT_MAXに設定できます。サンプルコード:

// サンプルコードのbaseStationNumberパラメーターは、インデックステーブルのBaseStationNumber列に対応します。
// サンプルコードのstartTimeパラメーターは、インデックステーブルのStartTime列に対応します。startTimeパラメーターは、クエリする時間の範囲の開始を指定します。
private static void getRangeFromIndexTable(SyncClient client,
                                           long baseStationNumber,
                                           long startTime) {
    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(INDEX1_NAME);

    // 開始プライマリキー列を指定します。
    PrimaryKeyBuilder startPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    startPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_3, PrimaryKeyValue.fromLong(baseStationNumber));
    startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromLong(startTime));
    startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MIN);
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKeyBuilder.build());

    // 終了プライマリキー列を指定します。
    PrimaryKeyBuilder endPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    endPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_3, PrimaryKeyValue.fromLong(baseStationNumber));
    endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MAX);
    endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MAX);
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endPrimaryKeyBuilder.build());

    rangeRowQueryCriteria.setMaxVersions(1);

    String strBaseStationNum = String.format("%d", baseStationNumber);
    String strStartTime = String.format("%d", startTime);
    System.out.println("基地局" + strBaseStationNum + "によって転送された、" + strStartTime + "から始まるすべての着信番号がリストされています:");
    while (true) {
        GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
        for (Row row : getRangeResponse.getRows()) {
            System.out.println(row);
        }

        // nextStartPrimaryKeyの値がnullでない場合は、データの読み取りを続けます。
        if (getRangeResponse.getNextStartPrimaryKey() != null) {
            rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
        } else {
            break;
        }
    }
}

BaseStationNumber列の値が3で、StartTime列の値が1532574861から1532584054の範囲である行のDuration列の値をクエリする

このクエリは、BaseStationNumber列とStartTime列の値に基づいて条件を指定し、Duration列の値のみを返します。「BaseStationNumber列の値が2で、StartTime列の値が1532574740である行をクエリする」セクションで作成されたIndexOnBaseStation1インデックステーブルからデータをクエリして、クエリ条件を満たす行のプライマリキーを取得できます。次に、プライマリキーに基づいてデータテーブルからデータをクエリし、Duration列の値を取得します。

インデックステーブルの最初のプライマリキー列は、データテーブルの最初のプライマリキー列とは異なります。したがって、インデックスタイプはグローバルセカンダリインデックスです。

サンプルコード:

// サンプルコードのbaseStationNumberパラメーターは、インデックステーブルのBaseStationNumber列に対応します。
// サンプルコードのstartTimeパラメーターとendTimeパラメーターは、インデックステーブルのStartTime列に対応します。startTimeパラメーターとendTimeパラメーターは、クエリする時間の範囲の開始と終了を指定します。
// サンプルコードのDEFINED_COL_NAME_2パラメーターは、データテーブルのDuration列に対応します。
private static void getRowFromIndexAndMainTable(SyncClient client,
 long baseStationNumber,
 long startTime,
 long endTime) {
 RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(INDEX1_NAME);

 // 開始プライマリキー列を指定します。
 PrimaryKeyBuilder startPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
 startPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_3, PrimaryKeyValue.fromLong(baseStationNumber));
 startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromLong(startTime));
 startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MIN);
 rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKeyBuilder.build());

 // 終了プライマリキー列を指定します。
 PrimaryKeyBuilder endPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
 endPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_3, PrimaryKeyValue.fromLong(baseStationNumber));
 endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromLong(endTime));
 endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MAX);
 rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endPrimaryKeyBuilder.build());

 rangeRowQueryCriteria.setMaxVersions(1);

 String strBaseStationNum = String.format("%d", baseStationNumber);
 String strStartTime = String.format("%d", startTime);
 String strEndTime = String.format("%d", endTime);

 System.out.println("基地局" + strBaseStationNum + "によって転送された、" + strStartTime + "から" + strEndTime + "までの通話時間がリストされています:");
 while (true) {
 GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
 for (Row row : getRangeResponse.getRows()) {
 PrimaryKey curIndexPrimaryKey = row.getPrimaryKey();
 // データテーブルのプライマリキー列を指定します。
 PrimaryKeyColumn mainCalledNumber = curIndexPrimaryKey.getPrimaryKeyColumn(PRIMARY_KEY_NAME_1);
 PrimaryKeyColumn callStartTime = curIndexPrimaryKey.getPrimaryKeyColumn(PRIMARY_KEY_NAME_2);
 PrimaryKeyBuilder mainTablePKBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
 mainTablePKBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, mainCalledNumber.getValue());
 mainTablePKBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, callStartTime.getValue());
 PrimaryKey mainTablePK = mainTablePKBuilder.build(); 

 // データテーブルからデータをクエリします。
 SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, mainTablePK);
 // データテーブルのDuration列からデータを読み取ります。
 criteria.addColumnsToGet(DEFINED_COL_NAME_2); 
 // 最新バージョンのデータを読み取るには、maxVersionsパラメーターを1に設定します。
 criteria.setMaxVersions(1);
 GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
 Row mainTableRow = getRowResponse.getRow();

 System.out.println(mainTableRow);
 }

 // nextStartPrimaryKeyの値がnullでない場合は、データの読み取りを続けます。
 if (getRangeResponse.getNextStartPrimaryKey() != null) {
 rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
 } else {
 break;
 }
 }
}

クエリ効率を向上させるには、BaseStationNumber列とStartTime列に基づいてIndexOnBaseStation2という名前のインデックステーブルを作成し、Duration列をインデックステーブルの属性列として指定できます。次に、GetRange操作を呼び出してインデックステーブルをスキャンし、クエリ条件を満たす行を取得します。

インデックステーブルのデータ

次の表に、IndexOnBaseStation2インデックステーブルのデータを示します。

PK0

PK1

PK2

Defined0

BaseStationNumber

StartTime

CellNumber

Duration

1

1532574644

123456

60

1

1532574714

234567

10

2

1532574795

345678

5

2

1532574861

345678

100

3

1532574734

234567

20

3

1532584054

456789

200

GetRange操作を呼び出してデータをクエリするときに、BaseStationNumber列の最大値と最小値の両方を3に設定し、StartTime列の最小値と最大値を1532574861と1532584054に設定し、CellNumber列の最小値と最大値をINT_MINとINT_MAXに設定できます。

サンプルコード:

// サンプルコードのbaseStationNumberパラメーターは、インデックステーブルのBaseStationNumber列に対応します。
// サンプルコードのstartTimeパラメーターとendTimeパラメーターは、インデックステーブルのStartTime列に対応します。startTimeパラメーターとendTimeパラメーターは、クエリする時間の範囲の開始と終了を指定します。
// サンプルコードのDEFINED_COL_NAME_2パラメーターは、インデックステーブルのDuration列に対応します。
private static void getRangeFromIndexTable(SyncClient client,
 long baseStationNumber,
 long startTime,
 long endTime) {
 RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(INDEX2_NAME);

 // 開始プライマリキー列を指定します。
 PrimaryKeyBuilder startPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
 startPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_3, PrimaryKeyValue.fromLong(baseStationNumber));
 startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromLong(startTime));
 startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MIN);
 rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKeyBuilder.build());

 // 終了プライマリキー列を指定します。
 PrimaryKeyBuilder endPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
 endPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_3, PrimaryKeyValue.fromLong(baseStationNumber));
 endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromLong(endTime));
 endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MAX);
 rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endPrimaryKeyBuilder.build());

 // データを読み取る列を指定します。
 rangeRowQueryCriteria.addColumnsToGet(DEFINED_COL_NAME_2);

 rangeRowQueryCriteria.setMaxVersions(1);

 String strBaseStationNum = String.format("%d", baseStationNumber);
 String strStartTime = String.format("%d", startTime);
 String strEndTime = String.format("%d", endTime);

 System.out.println("基地局" + strBaseStationNum + "によって転送された、" + strStartTime + "から" + strEndTime + "までの通話時間がリストされています:");
 while (true) {
 GetRangeResponse getRangeResponse = client.getRange(newGetRangeRequest(rangeRowQueryCriteria));
 for (Row row : getRangeResponse.getRows()) {
 System.out.println(row);
 }

 // nextStartPrimaryKeyの値がnullでない場合は、データの読み取りを続けます。
 if (getRangeResponse.getNextStartPrimaryKey() != null) {
 rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
 } else {
 break;
 }
 }
}

CellNumber列の値が456789で、CalledNumber列の値が345678である行をクエリするCellNumber 列の値が 456789 で、CalledNumber 列の値が 345678 である行をクエリします

このクエリは、CellNumber列とCalledNumber列の値に基づいて条件を指定します。CalledNumber列は、データテーブルの事前定義された列です。データテーブルから直接クエリすることはできません。CellNumber列とCalledNumber列に基づいてLocalIndexOnBeCalledNumberという名前のインデックステーブルを作成し、CellNumber列とCalledNumber列をインデックステーブルのプライマリキー列として指定し、Duration列とBaseStationNumber列をインデックステーブルの属性列として指定する必要があります。次に、GetRange操作を呼び出してインデックステーブルをスキャンし、クエリ条件を満たす行を取得します。

インデックステーブルの最初のプライマリキー列は、データテーブルの最初のプライマリキー列と同じです。したがって、インデックスタイプはローカルセカンダリインデックスです。

インデックステーブルのデータ

次の表に、LocalIndexOnBeCalledNumberインデックステーブルのデータを示します。

PK0

Defined0

PK1

Defined1

Defined2

CellNumber

CalledNumber

StartTime (UNIXタイムスタンプ)

Duration

BaseStationNumber

123456

654321

1532574644

60

1

234567

123456

1532574734

20

3

234567

765432

1532574714

10

1

345678

123456

1532574795

5

2

345678

123456

1532574861

100

2

456789

345678

1532584054

200

3

GetRange操作を呼び出してデータをクエリするときに、CellNumber列の最大値と最小値の両方を456789に設定し、CalledNumber列の最大値と最小値の両方を345678に設定し、StartTime列の最小値と最大値を0とINT_MAXに設定できます。サンプルコード:

// サンプルコードのcellNumberパラメーターとcalledNumberパラメーターは、インデックステーブルのCellNumber列とCalledNumber列に対応します。
private static void getRangeFromLocalIndex(SyncClient client, long cellNumber, long calledNumber){

    RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(INDEX3_NAME);

    // 開始プライマリキー列を指定します。
    PrimaryKeyBuilder startPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromLong(cellNumber));
    startPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.fromLong(calledNumber));
    startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromLong(0));
    rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKeyBuilder.build());

    // 終了プライマリキー列を指定します。
    PrimaryKeyBuilder endPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromLong(cellNumber));
    endPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.fromLong(calledNumber));
    endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MAX);
    rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endPrimaryKeyBuilder.build());

    rangeRowQueryCriteria.setMaxVersions(1);

    String strNum = String.format("%d", cellNumber);
    String strCalledNum = String.format("%d", calledNumber);
    System.out.println("発信番号" + strNum + "と着信番号" +strCalledNum+ "の間のすべての通話記録がリストされています:");
    while (true) {
        GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
        for (Row row : getRangeResponse.getRows()) {
            System.out.println(row);
        }

        // nextStartPrimaryKeyの値がnullでない場合は、データの読み取りを続けます。
        if (getRangeResponse.getNextStartPrimaryKey() != null) {
            rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
        } else {
            break;
        }
    }
}

付録:データテーブルとセカンダリインデックステーブルを作成するためのサンプルコード

次のサンプルコードは、このトピックで使用されているデータテーブルとセカンダリインデックステーブルを作成する方法を示しています。インデックスタイプには、ローカルセカンダリインデックスとグローバルセカンダリインデックスが含まれます。

private static final String TABLE_NAME = "CallRecordTable";
private static final String INDEX0_NAME = "IndexOnBeCalledNumber";
private static final String INDEX1_NAME = "IndexOnBaseStation1";
private static final String INDEX2_NAME = "IndexOnBaseStation2";
private static final String INDEX3_NAME = "LocalIndexOnBeCalledNumber";
private static final String PRIMARY_KEY_NAME_1 = "CellNumber";
private static final String PRIMARY_KEY_NAME_2 = "StartTime";
private static final String DEFINED_COL_NAME_1 = "CalledNumber";
private static final String DEFINED_COL_NAME_2 = "Duration";
private static final String DEFINED_COL_NAME_3 = "BaseStationNumber";

private static void createTable(SyncClient client) {
    TableMeta tableMeta = new TableMeta(TABLE_NAME);
    tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(PRIMARY_KEY_NAME_1, PrimaryKeyType.INTEGER));
    tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(PRIMARY_KEY_NAME_2, PrimaryKeyType.INTEGER));
    tableMeta.addDefinedColumn(new DefinedColumnSchema(DEFINED_COL_NAME_1, DefinedColumnType.INTEGER));
    tableMeta.addDefinedColumn(new DefinedColumnSchema(DEFINED_COL_NAME_2, DefinedColumnType.INTEGER));
    tableMeta.addDefinedColumn(new DefinedColumnSchema(DEFINED_COL_NAME_3, DefinedColumnType.INTEGER));
    // データの有効期間(TTL)を指定します。単位:秒。値-1は、データが期限切れにならないことを示します。データテーブルに1つ以上のインデックステーブルがある場合は、timeToLiveの値を-1に設定する必要があります。
    int timeToLive = -1; 
    // 保持できるデータバージョンの最大数を指定します。データテーブルに1つ以上のインデックステーブルがある場合は、maxVersionsの値を1に設定する必要があります。
    int maxVersions = 1; 

    TableOptions tableOptions = new TableOptions(timeToLive, maxVersions);

    ArrayList<IndexMeta> indexMetas = new ArrayList<IndexMeta>();
 
    IndexMeta indexMeta0 = new IndexMeta(INDEX0_NAME);
    indexMeta0.addPrimaryKeyColumn(DEFINED_COL_NAME_1);
    indexMetas.add(indexMeta0);
   
    IndexMeta indexMeta1 = new IndexMeta(INDEX1_NAME);
    indexMeta1.addPrimaryKeyColumn(DEFINED_COL_NAME_3);
    indexMeta1.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2);
    indexMetas.add(indexMeta1);
   
    IndexMeta indexMeta2 = new IndexMeta(INDEX2_NAME);
    indexMeta2.addPrimaryKeyColumn(DEFINED_COL_NAME_3);
    indexMeta2.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2);
    indexMeta2.addDefinedColumn(DEFINED_COL_NAME_2);
    indexMetas.add(indexMeta2);
 
    IndexMeta indexMeta3 = new IndexMeta(INDEX3_NAME);
    indexMeta3.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1);
    indexMeta3.addPrimaryKeyColumn(DEFINED_COL_NAME_1);
    indexMeta3.addDefinedColumn(DEFINED_COL_NAME_2);
    indexMeta3.addDefinedColumn(DEFINED_COL_NAME_3);
    // indexUpdateModeの値をIUM_SYNC_INDEXに設定します。
    indexMeta3.setIndexUpdateMode(IUM_SYNC_INDEX);
    // indexTypeの値をIT_LOCAL_INDEXに設定します。
    indexMeta3.setIndexType(IT_LOCAL_INDEX);
    indexMetas.add(indexMeta3);
 
    CreateTableRequest request = new CreateTableRequest(tableMeta, tableOptions, indexMetas);

    client.createTable(request);
}