范围读取数据

更新时间:
复制 MD 格式

Java SDK 按主键范围读取数据表中的连续多行数据,支持正反向读取、按版本范围过滤、按列值过滤,适用于按主键区间批量扫描行数据的场景。

前提条件

安装 Tablestore Java SDK并初始化客户端。

功能说明

public GetRangeResponse getRange(GetRangeRequest getRangeRequest) throws TableStoreException, ClientException

按主键范围扫描数据表中的连续多行。通过 RangeRowQueryCriteria 指定起始和结束主键,结果通过 response.getRows() 获取行列表。

以下示例从数据表 get_range_demo 正向读取主键值大于等于 row1 的所有行,仅返回每列最新版本。

String tableName = "get_range_demo";

RangeRowQueryCriteria criteria = new RangeRowQueryCriteria(tableName);

// 起始主键(包含)
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
criteria.setInclusiveStartPrimaryKey(startPkBuilder.build());

// 结束主键(不包含),INF_MAX 表示无限大
PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endPkBuilder.build());

criteria.setMaxVersions(1);

GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("RequestId: " + response.getRequestId());
System.out.println("Read CU: " + response.getConsumedCapacity().getCapacityUnit().getReadCapacityUnit());
for (Row row : response.getRows()) {
    System.out.println(row);
}
说明

单次范围扫描数据上限为 5000 行或者 4 MB。超出限制时,响应中的 nextStartPrimaryKey 返回下一页起始主键,需循环调用读取剩余数据。

关键参数

  • tableName(必选):读取的数据表名称。

  • inclusiveStartPrimaryKey(必选):起始主键,包含该主键。

  • exclusiveEndPrimaryKey(必选):结束主键,不包含该主键。

  • maxVersionstimeRange(二选一):最大版本数或数据版本范围。

参数说明

通过 RangeRowQueryCriteria 携带查询条件,各参数说明如下。

名称

类型

说明

tableName(必选)

String

读取的数据表名称。

inclusiveStartPrimaryKey(必选)

PrimaryKey

起始主键信息,包括主键列名称和主键值。

  • 返回数据包含起始主键。

  • 主键个数和类型必须与数据表的主键 schema 保持一致。

  • 正向读取时,起始主键必须小于结束主键。

  • 反向读取时,起始主键必须大于结束主键。

  • PrimaryKeyValue.INF_MIN 表示无限小,PrimaryKeyValue.INF_MAX 表示无限大。

exclusiveEndPrimaryKey(必选)

PrimaryKey

结束主键信息,包括主键列名称和主键值。

  • 返回数据不包含结束主键。

  • 主键个数和类型必须与数据表的主键 schema 保持一致。

  • PrimaryKeyValue.INF_MIN 表示无限小,PrimaryKeyValue.INF_MAX 表示无限大。

direction(可选)

Direction

读取方向。

  • FORWARD:默认值,正向读取。

  • BACKWARD:反向读取。

maxVersions(二选一)

OptionalValue<Integer>

最大版本数。maxVersionstimeRange 必须至少设置一个。

如果符合查询条件的数据版本数量超过设置的最大版本数,按从新到旧的顺序返回指定版本数量的数据。

timeRange(二选一)

OptionalValue<TimeRange>

数据版本范围。maxVersionstimeRange 必须至少设置一个。

数据表的每个属性列可以有不同的数据版本,设置版本范围后仅返回该范围内的数据。

limit(可选)

int

单次返回最大行数,必须大于 0。

如果符合查询条件的数据行数大于设置的值,返回指定的最大行数和用于下一次查询的起始主键值。

columnsToGet(可选)

Set<String>

指定读取的数据列,可以是主键列或属性列。

  • 不设置 columnsToGet 时,返回整行数据。

  • 设置后如果读取的行数据不包含任何指定的数据列,不返回该行数据。

filter(可选)

OptionalValue<Filter>

过滤条件,详情请参见过滤器

如果同时设置 columnsToGetfilter,先按 columnsToGet 筛选数据列,再按 filter 条件过滤数据。

场景示例

分页迭代读取

单次响应最多返回 5000 行或 4 MB。响应中的 nextStartPrimaryKey 为下一页起始主键,循环调用直至返回 null 即扫完全部数据。

String tableName = "get_range_demo";

RangeRowQueryCriteria criteria = new RangeRowQueryCriteria(tableName);

PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MIN);
criteria.setInclusiveStartPrimaryKey(startPkBuilder.build());

PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endPkBuilder.build());

criteria.setMaxVersions(1);

int totalRows = 0;
while (true) {
    GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
    totalRows += response.getRows().size();

    // 单次响应未读完,使用 nextStartPrimaryKey 继续下一页
    PrimaryKey nextStart = response.getNextStartPrimaryKey();
    if (nextStart == null) {
        break;
    }
    criteria.setInclusiveStartPrimaryKey(nextStart);
}
System.out.println("Total rows scanned: " + totalRows);

反向读取

通过 setDirection(Direction.BACKWARD) 反向扫描。反向读取时起始主键必须大于结束主键。

String tableName = "get_range_demo";

RangeRowQueryCriteria criteria = new RangeRowQueryCriteria(tableName);
criteria.setDirection(Direction.BACKWARD);

// 反向读取时,起始主键必须大于结束主键
PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setInclusiveStartPrimaryKey(startPkBuilder.build());

PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"));
criteria.setExclusiveEndPrimaryKey(endPkBuilder.build());

criteria.setMaxVersions(1);

GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("Rows (backward): " + response.getRows().size());

条件过滤读取

通过 setFilter 设置列值过滤条件,仅返回符合条件的行。

String tableName = "get_range_demo";

RangeRowQueryCriteria criteria = new RangeRowQueryCriteria(tableName);

PrimaryKeyBuilder startPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
startPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MIN);
criteria.setInclusiveStartPrimaryKey(startPkBuilder.build());

PrimaryKeyBuilder endPkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
endPkBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.INF_MAX);
criteria.setExclusiveEndPrimaryKey(endPkBuilder.build());

criteria.setMaxVersions(1);

// 仅返回 col1 等于 "val1" 的行
SingleColumnValueFilter filter = new SingleColumnValueFilter(
        "col1",
        SingleColumnValueFilter.CompareOperator.EQUAL,
        ColumnValue.fromString("val1"));
filter.setPassIfMissing(false);
criteria.setFilter(filter);

GetRangeResponse response = client.getRange(new GetRangeRequest(criteria));
System.out.println("Rows (filtered): " + response.getRows().size());

相关文档