使用 Java SDK 通过全局二级索引或本地二级索引读取数据。
前提条件
安装Tablestore Java SDK并初始化客户端。
功能说明
二级索引通过重新组合数据表的主键列和预定义列,提供不同于数据表主键的读取路径。索引表只能用于读取数据。索引表中包含索引主键、系统自动补充的数据表主键,以及创建索引时指定的属性列;如需获取索引表中未包含的属性列,需根据返回的数据表主键反查数据表。关于二级索引的更多信息,请参见二级索引。
读取索引表时,主键列的名称和顺序必须与索引表的主键结构一致。例如,数据表以 user_id、order_id 为主键,二级索引使用 category 作为新增索引列时,两类索引表的完整主键顺序如下。
|
索引类型 |
创建索引时指定的索引主键 |
索引表的完整主键顺序 |
|
全局二级索引 |
|
|
|
本地二级索引 |
|
|
创建全局二级索引并同步存量数据时,在存量数据构造和同步完成前不能读取索引表。请等待存量数据同步完成后再读取。
调用 getRow 根据完整的索引表主键读取单行数据。
public GetRowResponse getRow(GetRowRequest getRowRequest)
throws TableStoreException, ClientException
调用 getRange 按索引表主键范围读取数据。
public GetRangeResponse getRange(GetRangeRequest getRangeRequest)
throws TableStoreException, ClientException
以下示例根据完整主键从全局二级索引 example_global_index 读取一行数据,并仅返回 status 属性列。
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("category", PrimaryKeyValue.fromString("books"))
.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("user-1"))
.addPrimaryKeyColumn("order_id", PrimaryKeyValue.fromLong(101L))
.build();
SingleRowQueryCriteria criteria =
new SingleRowQueryCriteria("example_global_index", primaryKey);
criteria.addColumnsToGet("status");
criteria.setMaxVersions(1);
GetRowResponse response = client.getRow(new GetRowRequest(criteria));
System.out.println(response.getRow());
参数说明
单行读取参数
GetRowRequest 包含以下参数。
|
名称 |
类型 |
说明 |
|
rowQueryCriteria(必选) |
|
单行读取条件。 |
单行读取条件
rowQueryCriteria 的类型为 SingleRowQueryCriteria,包含以下参数。
|
名称 |
类型 |
说明 |
|
tableName(必选) |
|
索引表名称。 |
|
primaryKey(必选) |
|
待读取行的完整索引表主键。必须包含创建索引时指定的索引主键和系统自动补充的数据表主键,主键列的名称和顺序必须与索引表定义一致。 |
|
columnsToGet(可选) |
|
需要返回的属性列名称,最多指定 128 列。不设置时返回索引表中该行的全部属性列。索引表中未包含的属性列不会返回,需反查数据表获取。 |
|
maxVersions(条件必选) |
|
每个属性列最多返回的版本数,必须大于 0。二级索引仅保留最新版本,通常设置为 |
|
timeRange(条件必选) |
|
属性列版本的时间戳范围,单位为毫秒,范围为前闭后开区间。与 |
|
filter(可选) |
|
服务端过滤条件。条件不匹配时不返回该行。 |
|
startColumn(可选) |
|
返回属性列的起始列名,按列名字典序排序,结果包含该列。主要用于宽行读取。 |
|
endColumn(可选) |
|
返回属性列的结束列名,按列名字典序排序,结果不包含该列。主要用于宽行读取。 |
范围读取参数
GetRangeRequest 包含以下参数。
|
名称 |
类型 |
说明 |
|
rangeRowQueryCriteria(必选) |
|
范围读取条件。 |
范围读取条件
rangeRowQueryCriteria 的类型为 RangeRowQueryCriteria,包含以下参数。
|
名称 |
类型 |
说明 |
|
tableName(必选) |
|
索引表名称。 |
|
inclusiveStartPrimaryKey(必选) |
|
读取范围的起始主键,结果包含该主键。必须包含索引表的全部主键列。可使用 |
|
exclusiveEndPrimaryKey(必选) |
|
读取范围的结束主键,结果不包含该主键。必须包含索引表的全部主键列。可使用 |
|
direction(可选) |
|
读取方向。取值为 |
|
limit(可选) |
|
单次请求最多返回的行数,必须大于 0。默认值为 |
|
columnsToGet(可选) |
|
需要返回的属性列名称,最多指定 128 列。不设置时返回索引表中各行的全部属性列。如果某行中指定的属性列均不存在,则不返回该行;需要反查数据表时,应先读取索引表中实际存在的列或不设置此参数。 |
|
maxVersions(条件必选) |
|
每个属性列最多返回的版本数,必须大于 0。二级索引仅保留最新版本,通常设置为 |
|
timeRange(条件必选) |
|
属性列版本的时间戳范围,单位为毫秒,范围为前闭后开区间。与 |
|
filter(可选) |
|
服务端过滤条件,只返回满足条件的行。 |
|
startColumn(可选) |
|
返回属性列的起始列名,按列名字典序排序,结果包含该列。主要用于宽行读取。 |
|
endColumn(可选) |
|
返回属性列的结束列名,按列名字典序排序,结果不包含该列。主要用于宽行读取。 |
返回值
单行读取返回值
GetRowResponse 包含以下返回参数。
|
名称 |
类型 |
说明 |
|
row |
|
返回的行数据。待读取行不存在时返回 |
|
consumedCapacity |
|
本次操作消耗的服务能力单元。 |
范围读取返回值
GetRangeResponse 包含以下返回参数。
|
名称 |
类型 |
说明 |
|
rows |
|
本次请求返回的行数据。 |
|
nextStartPrimaryKey |
|
下一次读取的起始主键。返回值不为 |
|
consumedCapacity |
|
本次操作消耗的服务能力单元。 |
场景示例
按全局二级索引范围读取数据
以下示例从全局二级索引 example_global_index 读取 category 为 books 的数据,并处理分页返回的 nextStartPrimaryKey。
PrimaryKey startPrimaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("category", PrimaryKeyValue.fromString("books"))
.addPrimaryKeyColumn("user_id", PrimaryKeyValue.INF_MIN)
.addPrimaryKeyColumn("order_id", PrimaryKeyValue.INF_MIN)
.build();
PrimaryKey endPrimaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("category", PrimaryKeyValue.fromString("books"))
.addPrimaryKeyColumn("user_id", PrimaryKeyValue.INF_MAX)
.addPrimaryKeyColumn("order_id", PrimaryKeyValue.INF_MAX)
.build();
RangeRowQueryCriteria rangeCriteria =
new RangeRowQueryCriteria("example_global_index");
rangeCriteria.setInclusiveStartPrimaryKey(startPrimaryKey);
rangeCriteria.setExclusiveEndPrimaryKey(endPrimaryKey);
rangeCriteria.setMaxVersions(1);
rangeCriteria.setLimit(100);
List<Row> rows = new ArrayList<>();
while (true) {
GetRangeResponse response =
client.getRange(new GetRangeRequest(rangeCriteria));
rows.addAll(response.getRows());
if (response.getNextStartPrimaryKey() == null) {
break;
}
rangeCriteria.setInclusiveStartPrimaryKey(
response.getNextStartPrimaryKey());
}
rows.forEach(System.out::println);
反查数据表获取属性列
以下示例沿用上一示例返回的 rows,从索引表主键中提取数据表主键,并反查数据表 example_table 获取索引表中未包含的 detail 属性列。
for (Row indexRow : rows) {
PrimaryKey indexPrimaryKey = indexRow.getPrimaryKey();
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn(
"user_id",
indexPrimaryKey.getPrimaryKeyColumn("user_id").getValue())
.addPrimaryKeyColumn(
"order_id",
indexPrimaryKey.getPrimaryKeyColumn("order_id").getValue())
.build();
SingleRowQueryCriteria rowCriteria =
new SingleRowQueryCriteria("example_table", primaryKey);
rowCriteria.addColumnsToGet("detail");
rowCriteria.setMaxVersions(1);
GetRowResponse response =
client.getRow(new GetRowRequest(rowCriteria));
System.out.println(response.getRow());
}