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

:ページングクエリを活用する方法

最終更新日:Mar 23, 2020

制約

従来のリレーショナルデータベースでサポートされていたページングクエリとは異なり、 NoSQL データモデルと API のページ機能には次の制約があります。

  • 範囲全体の行数を取得できません。つまり、合計ページ数を計算することはできません。
  • オフセット・フィルターをクライアント上で実行し、サーバーがスキャンして読み取ったデータが固定されているため、ページ・ジャンプにオフセットを設定することはお勧めしません。オフセット値が大きすぎると、クエリに時間がかかることがあります。
  • シーケンシャルページングのみがサポートされています。

サンプルコード

以下は、ページングされた読み込み API を実装するためのサンプルコードです。この API には、オフセットフィルタが含まれ、指定された数のページのデータが読み込まれます。

  1. /**
  2. * Query data in the specified range, return data on pages of specified numbers, and skip some rows according to the offset value.
  3. */
  4. private static Pair<List<Row>, RowPrimaryKey> readByPage(OTSClient client, String tableName,
  5. RowPrimaryKey startKey, RowPrimaryKey endKey, int offset, int pageSize) {
  6. Preconditions.checkArgument(offset >= 0, "Offset should not be negative.");
  7. Preconditions.checkArgument(pageSize > 0, "Page size should be greater than 0.");
  8. List<Row> rows = new ArrayList<Row>(pageSize);
  9. int limit = pageSize;
  10. int skip = offset;
  11. RowPrimaryKey nextStart = startKey;
  12. // If too much data needs to be queried, not all the data is returned through one request. You must perform stream query to obtain the data.
  13. while (limit > 0 && nextStart != null) {
  14. // Construct a query parameter of GetRange.
  15. // NOTE: Set the startPrimaryKey to the last point that has been read, so that the steam query continues from the point that has not been read yet in the previous operation.
  16. RangeRowQueryCriteria criteria = new RangeRowQueryCriteria(tableName);
  17. criteria.setInclusiveStartPrimaryKey(nextStart);
  18. criteria.setExclusiveEndPrimaryKey(endKey);
  19. // Correctly set the limit. The number of data rows expected to be read is at most a complete page of data and data that needs to be filtered (offset).
  20. criteria.setLimit(skip + limit);
  21. GetRangeRequest request = new GetRangeRequest();
  22. request.setRangeRowQueryCriteria(criteria);
  23. GetRangeResult response = client.getRange(request);
  24. for (Row row : response.getRows()) {
  25. if (skip > 0) {
  26. skip--; // Data before offset must be filtered out. The policy is reading the data first and then filtering the data on the client.
  27. } else {
  28. rows.add(row);
  29. limit--;
  30. }
  31. }
  32. // Set the start point for the next query.
  33. nextStart = response.getNextStartPrimaryKey();
  34. }
  35. return new Pair<List<Row>, RowPrimaryKey>(rows, nextStart);
  36. }

以下は、上記の API を使用して、指定された範囲内のすべてのデータをページ単位で読み取る例です。

  1. private static void readByPage(OTSClient client, String tableName) {
  2. int pageSize = 8;
  3. int offset = 33;
  4. RowPrimaryKey startKey = new RowPrimaryKey();
  5. startKey.addPrimaryKeyColumn(COLUMN_GID_NAME, PrimaryKeyValue.INF_MIN);
  6. startKey.addPrimaryKeyColumn(COLUMN_UID_NAME, PrimaryKeyValue.INF_MIN);
  7. RowPrimaryKey endKey = new RowPrimaryKey();
  8. endKey.addPrimaryKeyColumn(COLUMN_GID_NAME, PrimaryKeyValue.INF_MAX);
  9. endKey.addPrimaryKeyColumn(COLUMN_UID_NAME, PrimaryKeyValue.INF_MAX);
  10. // Start reading data of the row with offset = 33 in the range on the first page.
  11. Pair<List<Row>, RowPrimaryKey> result = readByPage(client, tableName, startKey, endKey, offset, pageSize);
  12. for (Row row : result.getKey()) {
  13. System.out.println(row.getColumns());
  14. }
  15. System.out.println("Total rows count: " + result.getKey().size());
  16. // Read data on the following pages in sequence until all the data in the range is read.
  17. startKey = result.getValue();
  18. while (startKey != null) {
  19. System.out.println("============= start read next page ==============");
  20. result = readByPage(client, tableName, startKey, endKey, 0, pageSize);
  21. for (Row row : result.getKey()) {
  22. System.out.println(row.getColumns());
  23. }
  24. startKey = result.getValue();
  25. System.out.println("Total rows count: " + result.getKey().size());
  26. }
  27. }

注: こちらをクリックして完全な例をダウンロードしてください。